- 링크결제 API 수정

- 지급대행 수정
This commit is contained in:
HyeonJongKim
2025-10-21 14:24:51 +09:00
parent c3fbb91888
commit ab5bea6aeb
30 changed files with 784 additions and 590 deletions

View File

@@ -21,6 +21,8 @@ export const PayoutDetailPage = () => {
const tid = location.state.tid;
const mid = location.state.mid;
const [requestType, setRequestType] = useState<string>('');
const [email, setEmail] = useState<string>('');
const [detail, setDetail] = useState<ExtensionPayoutDetailResponse>();
const { mutateAsync: extensionPayoutDetail } = useExtensionPayoutDetailMutation();
@@ -48,6 +50,8 @@ export const PayoutDetailPage = () => {
let params: ExtensionPayoutDetailDownloadCertificateParams = {
tid: tid,
mid: mid,
requestType: requestType,
email: email
};
extensionPayoutDetailDownloadCertification(params).then((rs: ExtensionPayoutDetailDownloadCertificateResponse) => {
console.log(rs);
@@ -74,8 +78,8 @@ export const PayoutDetailPage = () => {
></NumericFormat>
</span>
</div>
<div className="num-store"></div>
<div className="num-day">2025.08.19</div>
<div className="num-store">{detail?.companyName}</div>
<div className="num-day">{detail?.settlementDate}</div>
<div className="receipt-row">
<button
className="receipt-btn"
@@ -105,7 +109,7 @@ export const PayoutDetailPage = () => {
</li>
<li className="kv-row">
<span className="k"></span>
<span className="v">{ detail?.settlementDate }</span>
<span className="v">{ detail?.settlementDateTime }</span>
</li>
<li className="kv-row">
<span className="k"></span>

View File

@@ -1,6 +1,6 @@
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { HeaderType, SortTypeKeys } from '@/entities/common/model/types';
import { DefaultRequestPagination, HeaderType, SortTypeKeys } from '@/entities/common/model/types';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useExtensionPayoutListMutation } from '@/entities/additional-service/api/payout/use-extension-payout-list-mutation';
import {
@@ -10,11 +10,11 @@ import {
ExtensionPayoutListResponse,
PayoutContent,
PayoutDisbursementStatus,
PayoutSearchCl
PayoutSearchDateType
} from '@/entities/additional-service/model/payout/types';
import { useEffect, useState } from 'react';
import { JSX, useEffect, useState } from 'react';
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
import {
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode,
@@ -28,22 +28,44 @@ import { PayoutDisbursementStatusBtnGroup } from '@/entities/additional-service/
import { ListDateGroup } from '@/entities/additional-service/ui/list-date-group';
import { AdditionalServiceCategory } from '@/entities/additional-service/model/types';
import { useStore } from '@/shared/model/store';
import useIntersectionObserver from '@/widgets/intersection-observer';
export const PayoutListPage = () => {
const { navigate } = useNavigate();
const userMid = useStore.getState().UserStore.mid;
const [onActionIntersect, setOnActionIntersect] = useState<boolean>(false);
const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
entries.forEach((entry: IntersectionObserverEntry) => {
if (entry.isIntersecting) {
console.log('Element is now intersecting with the root. [' + onActionIntersect + ']');
if (onActionIntersect) {
callExtensionPayoutList();
}
}
else {
console.log('Element is no longer intersecting with the root.');
}
});
};
const { setTarget } = useIntersectionObserver({
threshold: 1,
onIntersect
});
const [sortType, setSortType] = useState<SortTypeKeys>(SortTypeKeys.LATEST);
const [listItems, setListItems] = useState<Record<string, Array<PayoutContent>>>({});
const [listItems, setListItems] = useState<Array<PayoutContent>>([]);
const [filterOn, setFilterOn] = useState<boolean>(false);
const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM);
const [nextCursor, setNextCursor] = useState<string | null>(null);
const [pageParam, setPageParam] = useState<DefaultRequestPagination>(DEFAULT_PAGE_PARAM);
const [mid, setMid] = useState<string>(userMid);
const [searchCl, setSearchCl] = useState<PayoutSearchCl>(PayoutSearchCl.REQUEST_DATE);
const [searchDateType, setSearchDateType] = useState<PayoutSearchDateType>(PayoutSearchDateType.REQUEST_DATE);
const [fromDate, setFromDate] = useState<string>(moment().format('YYYYMMDD'));
const [toDate, setToDate] = useState<string>(moment().format('YYYYMMDD'));
const [disbursementStatus, setDisbursementStatus] = useState<PayoutDisbursementStatus>(PayoutDisbursementStatus.ALL);
const [minAmount, setMinAmount] = useState<number>();
const [maxAmount, setMaxAmount] = useState<number>();
const [status, setStatus] = useState<PayoutDisbursementStatus>(PayoutDisbursementStatus.ALL);
const [minAmount, setMinAmount] = useState<number>(0);
const [maxAmount, setMaxAmount] = useState<number>(50000000);
const { mutateAsync: extensionPayoutList } = useExtensionPayoutListMutation();
const { mutateAsync: extensionPayoutExcel } = useExtensionPayoutExcelMutation();
@@ -58,22 +80,20 @@ export const PayoutListPage = () => {
const onClickToNavigation = () => {
navigate(PATHS.additionalService.payout.request);
};
const onClickToGoDetail = (tid?: string) => {
if(!!tid){
navigate(PATHS.additionalService.payout.detail, {
state: {
tid: tid
}
});
}
};
const callExtensionPayoutList = (option?: {
sortType?: SortTypeKeys,
val?: string
sortType?: SortTypeKeys,
status?: PayoutDisbursementStatus,
resetPage?: boolean
}) => {
pageParam.sortType = (option?.sortType)? option.sortType: sortType;
setPageParam(pageParam);
setOnActionIntersect(false);
const currentPageParam = option?.resetPage
? { ...DEFAULT_PAGE_PARAM, sortType: option?.sortType ?? sortType }
: { ...pageParam, sortType: option?.sortType ?? sortType };
setPageParam(currentPageParam);
let newMinAmount = minAmount;
if(!!minAmount && typeof(minAmount) === 'string'){
newMinAmount = parseInt(minAmount);
@@ -84,26 +104,41 @@ export const PayoutListPage = () => {
}
let params: ExtensionPayoutListParams = {
mid: mid,
searchCl: searchCl,
searchDateType: searchDateType,
fromDate: fromDate,
toDate: toDate,
disbursementStatus: disbursementStatus,
minAmount: minAmount,
maxAmount: maxAmount,
page: pageParam
status: option?.status ?? status,
minAmount: newMinAmount,
maxAmount: newMaxAmount,
page: currentPageParam
};
extensionPayoutList(params).then((rs: ExtensionPayoutListResponse) => {
setListItems(assembleData(rs.content));
// resetPage면 기존 리스트 무시, 아니면 추가
setListItems(option?.resetPage ? rs.content : [
...listItems,
...rs.content
]);
if (rs.hasNext) {
setNextCursor(rs.nextCursor);
setPageParam({
...currentPageParam,
cursor: rs.nextCursor
});
setOnActionIntersect(true)
}
else {
setNextCursor(null);
}
});
};
const callDownloadExcel = () => {
let params: ExtensionPayoutExcelParams = {
mid: mid,
searchCl: searchCl,
searchDateType: searchDateType,
fromDate: fromDate,
toDate: toDate,
disbursementStatus: disbursementStatus,
status: status,
minAmount: minAmount,
maxAmount: maxAmount,
};
@@ -112,29 +147,6 @@ export const PayoutListPage = () => {
});
};
const assembleData = (content: Array<PayoutContent>) => {
let data: any = {};
if(content && content.length > 0){
for(let i=0;i<content?.length;i++){
let date;
if(searchCl === PayoutSearchCl.REQUEST_DATE){
date = content[i]?.requestDate?.substring(0, 8);
}
else if(searchCl === PayoutSearchCl.PROXY_DATE){
date = content[i]?.settlementDate?.substring(0, 8);
}
let groupDate = moment(date).format('YYYYMMDD');
if(!!groupDate && !data.hasOwnProperty(groupDate)){
data[groupDate] = [];
}
if(!!groupDate && data.hasOwnProperty(groupDate)){
data[groupDate].push(content[i]);
}
}
}
return data;
};
const onClickToDownloadExcel = () => {
callDownloadExcel();
};
@@ -143,37 +155,79 @@ export const PayoutListPage = () => {
};
const onClickToSort = (sort: SortTypeKeys) => {
setSortType(sort);
callExtensionPayoutList({sortType: sort});
callExtensionPayoutList({
sortType: sort,
resetPage: true
});
};
const onClickToDisbursementStatus = (val: PayoutDisbursementStatus) => {
setDisbursementStatus(val);
setStatus(val);
callExtensionPayoutList({
val: val
status: val,
resetPage: true
});
};
useEffect(() => {
callExtensionPayoutList();
}, []);
// 필터 조건이 변경되면 첫 페이지부터 다시 시작
callExtensionPayoutList({ resetPage: true });
}, [
mid,
searchDateType,
fromDate,
toDate,
status,
minAmount,
maxAmount
]);
const getPayoutList = () => {
let rs = [];
if(Object.keys(listItems).length > 0){
for (const [key, value] of Object.entries(listItems)) {
rs.push(
<ListDateGroup
additionalServiceCategory={ AdditionalServiceCategory.Payout }
mid={ mid }
key={ key }
date={ key }
items={ value }
></ListDateGroup>
);
const getListDateGroup = () => {
let rs: JSX.Element[] = [];
let date = '';
let list: PayoutContent[] = [];
for (let i = 0; i < listItems.length; i++) {
// requestDate 또는 settlementDate format: "20211018140420" (YYYYMMDDHHmmss)
let itemDateStr = '';
if (searchDateType === PayoutSearchDateType.REQUEST_DATE) {
itemDateStr = listItems[i]?.requestDate || '';
} else if (searchDateType === PayoutSearchDateType.SETTLEMENT_DATE) {
itemDateStr = listItems[i]?.settlementDate || '';
}
let itemDate = itemDateStr.substring(0, 8);
if (i === 0) {
date = itemDate;
}
if (date !== itemDate) {
// 날짜가 바뀌면 이전 리스트를 푸시 (날짜 업데이트 전에!)
if (list.length > 0) {
rs.push(
<ListDateGroup
additionalServiceCategory={AdditionalServiceCategory.Payout}
mid={mid}
key={date + '-' + i}
date={date}
items={list as any}
></ListDateGroup>
);
}
date = itemDate; // 그 다음에 날짜 업데이트
list = [];
}
list.push(listItems[i] as any);
}
if (list.length > 0) {
rs.push(
<ListDateGroup
additionalServiceCategory={AdditionalServiceCategory.Payout}
mid={mid}
key={date + '-last'}
date={date}
items={list as any}
></ListDateGroup>
);
}
return rs;
}
};
return (
<>
@@ -234,7 +288,7 @@ export const PayoutListPage = () => {
PayoutDisbursementStatusBtnGroup.map((value, index) => (
<span
key={ `key-service-code=${ index }` }
className={ `keyword-tag ${(disbursementStatus === value.value)? 'active': ''}` }
className={ `keyword-tag ${(status === value.value)? 'active': ''}` }
onClick={ () => onClickToDisbursementStatus(value.value) }
>{ value.name }</span>
))
@@ -242,14 +296,15 @@ export const PayoutListPage = () => {
</div>
</div>
</section>
<div className="transaction-list">
{ getPayoutList() }
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={ () => onClickToNavigation() }
> </button>
</div>
<section className="transaction-list">
{ getListDateGroup() }
<div ref={setTarget}></div>
</section>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={ () => onClickToNavigation() }
> </button>
</div>
</div>
</div>
@@ -258,17 +313,17 @@ export const PayoutListPage = () => {
filterOn={ filterOn }
setFilterOn={ setFilterOn }
mid={ mid }
searchCl={ searchCl }
searchDateType={ searchDateType }
fromDate={ fromDate }
toDate={ toDate }
disbursementStatus= { disbursementStatus }
status= { status }
minAmount={ minAmount }
maxAmount={ maxAmount }
setMid={ setMid }
setSearchCl={ setSearchCl }
setSearchDateType={ setSearchDateType }
setFromDate={ setFromDate }
setToDate={ setToDate }
setDisbursementStatus={ setDisbursementStatus }
setStatus={ setStatus }
setMinAmount={ setMinAmount }
setMaxAmount={ setMaxAmount }
></PayoutFilter>

View File

@@ -13,6 +13,7 @@ import { useExtensionPayoutRequestMutation } from "@/entities/additional-service
import { ExtensionPayoutRequestParams, ExtensionPayoutRequestResponse } from "@/entities/additional-service/model/payout/types";
import NiceCalendar from "@/shared/ui/calendar/nice-calendar";
import { useStore } from "@/shared/model/store";
import moment from 'moment';
export const PayoutRequestPage = () => {
const { navigate } = useNavigate();
@@ -54,7 +55,7 @@ export const PayoutRequestPage = () => {
};
const setNewDate = (date: string) => {
setSettlementDate(date);
setSettlementDate(moment(date).format('YYYYMMDD'));
setCalendarOpen(false);
};
const onClickToOpenCalendar = () => {
@@ -68,7 +69,7 @@ export const PayoutRequestPage = () => {
<div className="ing-list">
<div className="billing-form gap-30">
<div className="billing-row">
<div className="billing-label">ID</div>
<div className="billing-label">ID<span>*</span></div>
<div className="billing-field">
<input
type="text"
@@ -78,7 +79,7 @@ export const PayoutRequestPage = () => {
</div>
</div>
<div className="billing-row">
<div className="billing-label"></div>
<div className="billing-label"><span>*</span></div>
<div className="billing-field">
<input
type="text"
@@ -88,7 +89,7 @@ export const PayoutRequestPage = () => {
</div>
</div>
<div className="billing-row">
<div className="billing-label"></div>
<div className="billing-label"><span>*</span></div>
<div className="billing-field">
<div className="input-wrapper date">
<input
@@ -101,6 +102,7 @@ export const PayoutRequestPage = () => {
className="date-btn"
type="button"
onClick={() => onClickToOpenCalendar()}
disabled={!isFormValid}
>
<img
src={IMAGE_ROOT + '/ico_date.svg'}