From ab5bea6aeb406827846e9e864b3de12e37f52a3f Mon Sep 17 00:00:00 2001 From: HyeonJongKim Date: Tue, 21 Oct 2025 14:24:51 +0900 Subject: [PATCH] =?UTF-8?q?-=20=EB=A7=81=ED=81=AC=EA=B2=B0=EC=A0=9C=20API?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20-=20=EC=A7=80=EA=B8=89=EB=8C=80?= =?UTF-8?q?=ED=96=89=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ension-link-pay-history-detail-mutation.ts | 2 +- .../lib/payment-status-utils.ts | 7 + .../additional-service/model/key-in/types.ts | 2 +- .../model/link-pay/constant.ts | 7 + .../model/link-pay/types.ts | 251 ++++-------------- .../model/payout/constant.ts | 6 +- .../additional-service/model/payout/types.ts | 16 +- .../ui/filter/payout-filter.tsx | 50 ++-- .../ui/fund-account/transfer-list-wrap.tsx | 6 +- .../ui/info-wrap/payment-info-wrap.tsx | 8 +- .../ui/info-wrap/title-info-wrap.tsx | 2 +- .../link-payment/apply/link-payment-step1.tsx | 23 +- .../filter/link-payment-history-filter.tsx | 76 +++--- .../link-payment-pending-send-filter.tsx | 24 +- .../link-payment-history-list.tsx | 45 +++- .../link-payment-history-wrap.tsx | 209 +++++++++------ .../link-payment/link-payment-wait-list.tsx | 45 +++- .../link-payment-wait-send-wrap.tsx | 173 +++++++----- .../additional-service/ui/list-date-group.tsx | 8 + .../additional-service/ui/list-item.tsx | 19 +- .../account-holder-search/request-page.tsx | 5 +- .../apply/link-payment-apply-confirm-page.tsx | 2 +- .../apply/link-payment-apply-page.tsx | 66 ++++- .../link-payment/link-payment-detail-page.tsx | 44 ++- .../link-payment-wait-detail-page.tsx | 7 +- .../additional-service/payout/detail-page.tsx | 10 +- .../additional-service/payout/list-page.tsx | 229 ++++++++++------ .../payout/request-page.tsx | 10 +- src/shared/ui/calendar/nice-calendar.tsx | 14 +- src/shared/ui/filter/single-date-picker.tsx | 8 +- 30 files changed, 784 insertions(+), 590 deletions(-) diff --git a/src/entities/additional-service/api/link-payment/use-extension-link-pay-history-detail-mutation.ts b/src/entities/additional-service/api/link-payment/use-extension-link-pay-history-detail-mutation.ts index b746341..ea6002d 100644 --- a/src/entities/additional-service/api/link-payment/use-extension-link-pay-history-detail-mutation.ts +++ b/src/entities/additional-service/api/link-payment/use-extension-link-pay-history-detail-mutation.ts @@ -29,7 +29,7 @@ export const extensionLinkPayHistoryDetail = async (params: ExtensionLinkPayHist buyerName: response.buyerName, sendMethod: response.sendMethod, sendDate: response.sendDate, - paymentStatus: response.paymentMethod, + paymentStatus: response.paymentStatus, failCount: response.failCount, paymentMethod: response.paymentMethod, paymentDate: response.paymentDate, diff --git a/src/entities/additional-service/lib/payment-status-utils.ts b/src/entities/additional-service/lib/payment-status-utils.ts index 1259ae0..ab36a85 100644 --- a/src/entities/additional-service/lib/payment-status-utils.ts +++ b/src/entities/additional-service/lib/payment-status-utils.ts @@ -2,6 +2,13 @@ export const getPaymentStatusText = (status?: string): string => { if (!status) return ''; const statusMap: Record = { + // 숫자 문자열 매핑 + '0': '미완료/활성화', + '1': '입금요청', + '2': '결제완료', + '3': '결제실패', + '4': '결제중단', + // 문자열 키 매핑 (하위 호환성) 'ALL': '전체', 'ACTIVE': '미완료/활성화', 'DEPOSIT_REQUEST': '입금요청', diff --git a/src/entities/additional-service/model/key-in/types.ts b/src/entities/additional-service/model/key-in/types.ts index 0b05482..58b290a 100644 --- a/src/entities/additional-service/model/key-in/types.ts +++ b/src/entities/additional-service/model/key-in/types.ts @@ -1,5 +1,5 @@ import { DefaulResponsePagination, DefaultRequestPagination } from "@/entities/common/model/types"; -import { AdditionalServiceCategory, ExtensionRequestParams, FilterProps, ListItemProps } from "../types"; +import { AdditionalServiceCategory, ExtensionRequestParams, FilterProps } from "../types"; // ======================================== // 키인결제 관련 타입들 diff --git a/src/entities/additional-service/model/link-pay/constant.ts b/src/entities/additional-service/model/link-pay/constant.ts index e69de29..e320d7a 100644 --- a/src/entities/additional-service/model/link-pay/constant.ts +++ b/src/entities/additional-service/model/link-pay/constant.ts @@ -0,0 +1,7 @@ +import { LinkPaymentProcessStatus } from "./types"; + +export const ProcessStatusBtnGrouup = [ + { name: '전체', value: LinkPaymentProcessStatus.ALL }, + { name: '발송요청', value: LinkPaymentProcessStatus.SEND_REQUEST }, + { name: '발송취소', value: LinkPaymentProcessStatus.SEND_CANCEL } +] \ No newline at end of file diff --git a/src/entities/additional-service/model/link-pay/types.ts b/src/entities/additional-service/model/link-pay/types.ts index 785306c..73f08d6 100644 --- a/src/entities/additional-service/model/link-pay/types.ts +++ b/src/entities/additional-service/model/link-pay/types.ts @@ -15,13 +15,11 @@ export interface LinkPaymentTabProps { } export enum LinkPaymentSearchCl { - ALL = "", PHONE = "PHONE_NUMBER", EMAIL = "EMAIL" } export enum LinkPaymentPaymentMethod { - ALL = "ALL", CARD = "CARD", BANK = "BANK", VIRTURE_BANK = "VIRTURE_BANK", @@ -34,15 +32,15 @@ export enum LinkPaymentPaymentMethod { } export enum LinkPaymentSendMethod { - ALL = "ALL", + ALL = "", SMS = "SMS", EMAIL = "EMAIL", KAKAO = "KAKAO" } export enum LinkPaymentPaymentStatus { - ALL = "ALL", - ACTIVATE = "ACTIVATE", + ALL = "", + ACTIVATE = "ACTIVE", DEPOSIT_REQUEST = "DEPOSIT_REQUEST", PAYMENT_COMPLETE = "PAYMENT_COMPLETE", PAYMENT_FAIL = "PAYMENT_FAIL", @@ -50,44 +48,60 @@ export enum LinkPaymentPaymentStatus { } export enum LinkPaymentSendStatus { - ALL = "ALL", + ALL = "", SUCCESS = "SUCCESS", FAIL = "FAIL" } +export enum LinkPaymentProcessStatus { + ALL = "", + SEND_REQUEST = "SEND_REQUEST", + SEND_CANCEL = "SEND_CANCEL" +} + export enum LinkContentType { BASIC = "BASIC", ADDITIONAL = "ADDITIONAL" } export interface LinkPaymentHistoryListItem { - tid?: string; - // TODO : buyerName 필요 - paymentDate?: string; - paymentStatus?: string; + requestId?: string; + cursorId?: string; + subReqId?: string; + mid?: string; + paymentMethod?: string; + detailExposure?: string; sendDate?: string; + buyerName?: string; + receiverInfo?: string; + orderId?: string; sendStatus?: string; - sendMethod?: string; - amount?: number; + paymentStatus?: string; + sendMethod?: LinkPaymentSendMethod; } export interface LinkPaymentWaitListItem { - tid?: string; + requestId?: string; scheduledSendDate?: string; - sendMethod?: string; - processStatus?: string; - // TODO: buyerName,phoneNumber 필요 + sendMethod?: LinkPaymentSendMethod; amount?: number; + processStatus?: LinkPaymentProcessStatus; + buyerName?: string; + receiverInfo?: string; } export interface LinkPaymentHistoryListProps { additionalServiceCategory: AdditionalServiceCategory; - listItems: Record>; + listItems: Array; + setTarget: (element: HTMLElement | null) => void; + mid: string; } export interface LinkPaymentWaitListProps { additionalServiceCategory: AdditionalServiceCategory; - listItems: Record>; + listItems: Array; + setTarget: (element: HTMLElement | null) => void; + mid: string; } export interface LinkPaymentHistoryFilterProps extends FilterProps { @@ -97,15 +111,15 @@ export interface LinkPaymentHistoryFilterProps extends FilterProps { fromDate: string; toDate: string; paymentStatus: LinkPaymentPaymentStatus; - processResult: ProcessResult; + sendStatus: LinkPaymentSendStatus; sendMethod: LinkPaymentSendMethod; setMid: (mid: string) => void; setSearchType: (searchType: LinkPaymentSearchCl) => void; setSearchKeyword: (searchKeyWorld: string) => void; setStartDate: (startDate: string) => void; setEndDate: (endDate: string) => void; - setTransactionStatus: (transactionStatus: LinkPaymentPaymentStatus) => void; - setProcessResult: (processResult: ProcessResult) => void; + setPaymentStatus: (transactionStatus: LinkPaymentPaymentStatus) => void; + setSendStatus: (sendStatus: LinkPaymentSendStatus) => void; setSendMethod: (sendMethod: LinkPaymentSendMethod) => void; } @@ -116,35 +130,35 @@ export interface LinkPaymentWaitFilterProps extends FilterProps { startDate: string; endDate: string; sendMethod: LinkPaymentSendMethod; - sendingStatus: LinkPaymentSendStatus; + processStatus: LinkPaymentProcessStatus; setMid: (mid: string) => void; setSearchType: (searchType: LinkPaymentSearchCl) => void; setSearchKeyword: (searchKeyWorld: string) => void; setStartDate: (startDate: string) => void; setEndDate: (endDate: string) => void; setSendMethod: (sendMethod: LinkPaymentSendMethod) => void; - setSendingStatus: (sendingStatus: LinkPaymentSendStatus) => void; - } + setProcessStatus: (sendingStatus: LinkPaymentProcessStatus) => void; +} // 링크 결제 - 발송,대기 조회 확장 서비스 // ======================================== export interface ExtensionLinkPayHistoryListParams extends ExtensionRequestParams { searchCl: string; searchValue: string; - paymentMethod: string; fromDate: string; toDate: string; - paymentStatus: string; - sendStatus: string; - sendMethod: string; + paymentStatus: LinkPaymentPaymentStatus; + sendStatus: LinkPaymentSendStatus; + sendMethod: LinkPaymentSendMethod; page?: DefaultRequestPagination; } export interface ExtensionLinkPayHistoryListResponse extends DefaulResponsePagination { - content: Array + content: Array } export interface ExtensionLinkPayHistoryDownloadExcelParams extends ExtensionRequestParams { + email: string; searchCl: string; searchValue: string; paymentMethod: string; @@ -164,7 +178,7 @@ export interface ExtensionLinkPayRequestParams extends ExtensionRequestParams { goodsName: string; amount: number; moid: string; - paymentExpiryDate: string; + paymentLimitDate: string; buyerName: string; email: string; phoneNumber: string; @@ -186,7 +200,7 @@ export interface LinkPaymentFormData { goodsName: string; amount: number; moid: string; - paymentExpiryDate: string; + paymentLimitDate: string; // Step 2 buyerName: string; email: string; @@ -198,169 +212,10 @@ export interface LinkPaymentFormData { linkContentType: LinkContentType; } -export interface ExtensionLinkPayHistoryDetailParams extends ExtensionRequestParams { - tid: string; -} - -export interface ExtensionLinkPayHistoryDetailResponse { - tid: string; - amount: number; - corpName: string; - sendDate: string; - buyerName: string; - sendMethod: string; - paymentStatus: string; - failCount: number; - paymentMethod: string; - paymentDate: string; - paymentLimitDate: string; - email: string; - phoneNumber: string; - goodsName: string; - moid: string; -} - -export interface ExtensionLinkPayHistoryResendParams extends ExtensionRequestParams { - tid: string; -} - -export interface ExtensionLinkPayHistoryResendResponse { - status: boolean -} - - -export interface ExtensionLinkPayWaitListParams extends ExtensionRequestParams { - searchCl: string; - searchValue: string; - fromDate: string; - toDate: string; - sendStatus: string; - sendMethod: string; - processStatus: string; - page?: DefaultRequestPagination; -} - -export interface ExtensionLinkPayWaitListResponse extends DefaulResponsePagination { - content: Array -} - -export interface ExtensionLinkPayWaitDownloadExcelParams extends ExtensionRequestParams { - searchCl: string; - searchValue: string; - fromDate: string; - toDate: string; - sendStatus: string; - sendMethod: string; - processStatus: string; -} - -export interface ExtensionLinkPayWaitDownloadExcelRespone { - status: boolean; -} - -export interface ExtensionLinkPayWaitDetailParams extends ExtensionRequestParams { - tid: string; -} - -export interface ExtensionLinkPayWaitDetailResponse { - tid: string; - amount: number; - corpName: string; - scheduledSendDate: string; - processStatus: string; - requestDate: string; - paymentLimitDate: string; - sendMethod: string; - buyerName: string - email: string; - phoneNumber: string; - goodsName: string; - moid: string; -} - -export interface ExtensionLinkPayWaitDeleteParams extends ExtensionRequestParams { - tid: string; -} - -export interface ExtensionLinkPayWaitDeleteRespone { - status: boolean -} - - -// 링크 결제 - 발송,대기 조회 확장 서비스 -// ======================================== -export interface ExtensionLinkPayHistoryListParams extends ExtensionRequestParams { - searchCl: string; - searchValue: string; - paymentMethod: string; - fromDate: string; - toDate: string; - paymentStatus: string; - sendStatus: string; - sendMethod: string; - page?: DefaultRequestPagination; -} - -export interface ExtensionLinkPayHistoryListResponse extends DefaulResponsePagination { - content: Array -} - -export interface ExtensionLinkPayHistoryDownloadExcelParams extends ExtensionRequestParams { - searchCl: string; - searchValue: string; - paymentMethod: string; - fromDate: string; - toDate: string; - paymentStatus: string; - sendStatus: string; - sendMethod: string; -} - -export interface ExtensionLinkPayHistoryDownloadExcelRespone { - status: boolean; -} - -export interface ExtensionLinkPayRequestParams extends ExtensionRequestParams { - sendMethod: string; - goodsName: string; - amount: number; - moid: string; - paymentExpiryDate: string; - buyerName: string; - email: string; - phoneNumber: string; - isIdentity: boolean; - identityType: IdentityType; - identityValue: string; - language: Language; - linkContentType: LinkContentType; -} - -export interface ExtensionLinkPayRequestResponse { - status: boolean -} - -export interface LinkPaymentFormData { - // Step 1 +export interface ExtensionLinkPayHistoryDetailParams { mid: string; - sendMethod: LinkPaymentSendMethod; - goodsName: string; - amount: number; - moid: string; - paymentExpiryDate: string; - // Step 2 - buyerName: string; - email: string; - phoneNumber: string; - isIdentity: boolean; - identityType: IdentityType; - identityValue: string; - language: Language; - linkContentType: LinkContentType; -} - -export interface ExtensionLinkPayHistoryDetailParams extends ExtensionRequestParams { - tid: string; + requestId: string; + subReqId: string; } export interface ExtensionLinkPayHistoryDetailResponse { @@ -382,7 +237,8 @@ export interface ExtensionLinkPayHistoryDetailResponse { } export interface ExtensionLinkPayHistoryResendParams extends ExtensionRequestParams { - tid: string; + requestId: string; + sendMethod?: string; } export interface ExtensionLinkPayHistoryResendResponse { @@ -395,7 +251,6 @@ export interface ExtensionLinkPayWaitListParams extends ExtensionRequestParams { searchValue: string; fromDate: string; toDate: string; - sendStatus: string; sendMethod: string; processStatus: string; page?: DefaultRequestPagination; @@ -406,11 +261,11 @@ export interface ExtensionLinkPayWaitListResponse extends DefaulResponsePaginati } export interface ExtensionLinkPayWaitDownloadExcelParams extends ExtensionRequestParams { + email: string; searchCl: string; searchValue: string; fromDate: string; toDate: string; - sendStatus: string; sendMethod: string; processStatus: string; } @@ -420,7 +275,7 @@ export interface ExtensionLinkPayWaitDownloadExcelRespone { } export interface ExtensionLinkPayWaitDetailParams extends ExtensionRequestParams { - tid: string; + requestId: string; } export interface ExtensionLinkPayWaitDetailResponse { @@ -440,7 +295,7 @@ export interface ExtensionLinkPayWaitDetailResponse { } export interface ExtensionLinkPayWaitDeleteParams extends ExtensionRequestParams { - tid: string; + requestId: string; } export interface ExtensionLinkPayWaitDeleteRespone { diff --git a/src/entities/additional-service/model/payout/constant.ts b/src/entities/additional-service/model/payout/constant.ts index 5eea8b1..80e69cd 100644 --- a/src/entities/additional-service/model/payout/constant.ts +++ b/src/entities/additional-service/model/payout/constant.ts @@ -1,8 +1,8 @@ -import { PayoutSearchCl, PayoutDisbursementStatus } from './types'; +import { PayoutSearchDateType, PayoutDisbursementStatus } from './types'; export const PayoutSearchClBtnGroup = [ - {name: '요청일자', value: PayoutSearchCl.REQUEST_DATE }, - {name: '지급일자', value: PayoutSearchCl.PROXY_DATE } + {name: '요청일자', value: PayoutSearchDateType.REQUEST_DATE }, + {name: '지급일자', value: PayoutSearchDateType.SETTLEMENT_DATE } ]; export const PayoutDisbursementStatusBtnGroup = [ {name: '전체', value: PayoutDisbursementStatus.ALL}, diff --git a/src/entities/additional-service/model/payout/types.ts b/src/entities/additional-service/model/payout/types.ts index 082bd45..976bb59 100644 --- a/src/entities/additional-service/model/payout/types.ts +++ b/src/entities/additional-service/model/payout/types.ts @@ -7,22 +7,22 @@ export interface ExtensionPayoutRequestParams { settlementDate: string; }; export interface ExtensionPayoutRequestResponse {}; -export enum PayoutSearchCl { +export enum PayoutSearchDateType { REQUEST_DATE = 'REQUEST_DATE', - PROXY_DATE = 'PROXY_DATE', + SETTLEMENT_DATE = 'SETTLEMENT_DATE', }; export enum PayoutDisbursementStatus { - ALL = 'ALL', + ALL = '', REQUEST = 'REQUEST', SUCCESS = 'SUCCESS', FAIL = 'FAIL', }; export interface ExtensionPayoutListParams { mid: string; - searchCl: PayoutSearchCl, + searchDateType: PayoutSearchDateType, fromDate: string; toDate: string; - disbursementStatus: PayoutDisbursementStatus; + status: PayoutDisbursementStatus; minAmount?: number; maxAmount?: number; page?: DefaultRequestPagination; @@ -54,6 +54,7 @@ export interface ExtensionPayoutDetailResponse { transTypeName: string; requestDate: string; settlementDate: string; + settlementDateTime: string; companyName: string; companyNo: string; accountName: string; @@ -62,6 +63,9 @@ export interface ExtensionPayoutDetailResponse { depositName: string; failReason: string; }; -export interface ExtensionPayoutDetailDownloadCertificateParams extends ExtensionPayoutDetailParams {}; +export interface ExtensionPayoutDetailDownloadCertificateParams extends ExtensionPayoutDetailParams { + requestType: string; + email: string; +}; export interface ExtensionPayoutDetailDownloadCertificateResponse {}; diff --git a/src/entities/additional-service/ui/filter/payout-filter.tsx b/src/entities/additional-service/ui/filter/payout-filter.tsx index 36be406..864a98c 100644 --- a/src/entities/additional-service/ui/filter/payout-filter.tsx +++ b/src/entities/additional-service/ui/filter/payout-filter.tsx @@ -7,7 +7,7 @@ import { FilterButtonGroups } from '@/shared/ui/filter/button-groups'; import { FilterRangeAmount } from '@/shared/ui/filter/range-amount'; import { PayoutDisbursementStatus, - PayoutSearchCl + PayoutSearchDateType } from '../../model/payout/types'; import { PayoutSearchClBtnGroup, @@ -25,47 +25,47 @@ export interface PayoutFilterProps { filterOn: boolean; setFilterOn: (filterOn: boolean) => void; mid: string; - searchCl: PayoutSearchCl; + searchDateType: PayoutSearchDateType; fromDate: string; toDate: string; - disbursementStatus: PayoutDisbursementStatus; - minAmount?: number; - maxAmount?: number; + status: PayoutDisbursementStatus; + minAmount: number; + maxAmount: number; setMid: (mid: string) => void; - setSearchCl: (searchCl: PayoutSearchCl) => void; + setSearchDateType: (searchDateType: PayoutSearchDateType) => void; setFromDate: (fromDate: string) => void; setToDate: (toDate: string) => void; - setDisbursementStatus: (disbursementStatus: PayoutDisbursementStatus) => void; - setMinAmount: (minAmount?: number) => void; - setMaxAmount: (maxAmount?: number) => void; + setStatus: (status: PayoutDisbursementStatus) => void; + setMinAmount: (minAmount: number) => void; + setMaxAmount: (maxAmount: number) => void; }; export const PayoutFilter = ({ filterOn, setFilterOn, mid, - searchCl, + searchDateType, fromDate, toDate, - disbursementStatus, + status, minAmount, maxAmount, setMid, - setSearchCl, + setSearchDateType, setFromDate, setToDate, - setDisbursementStatus, + setStatus, setMinAmount, setMaxAmount }: PayoutFilterProps) => { const [filterMid, setFilterMid] = useState(mid); - const [filterSearchCl, setFilterSearchCl] = useState(searchCl); + const [filterSearchDateType, setFilterSearchDateType] = useState(searchDateType); const [filterFromDate, setFilterFromDate] = useState(moment(fromDate).format('YYYY.MM.DD')); const [filterToDate, setFilterToDate] = useState(moment(toDate).format('YYYY.MM.DD')); - const [filterDisbursementStatus, setFilterDisbursementStatus] = useState(disbursementStatus); - const [filterMinAmount, setFilterMinAmount] = useState(minAmount); - const [filterMaxAmount, setFilterMaxAmount] = useState(maxAmount); + const [filterStatus, setFilterStatus] = useState(status); + const [filterMinAmount, setFilterMinAmount] = useState(minAmount); + const [filterMaxAmount, setFilterMaxAmount] = useState(maxAmount); const midOptions = useStore.getState().UserStore.selectOptionsMids; @@ -75,18 +75,18 @@ export const PayoutFilter = ({ const onClickToSetFilter = () => { setMid(filterMid); - setSearchCl(filterSearchCl); + setSearchDateType(filterSearchDateType); setFromDate(filterFromDate); setToDate(filterToDate); - setDisbursementStatus(filterDisbursementStatus); + setStatus(filterStatus); setMinAmount(filterMinAmount); setMaxAmount(filterMaxAmount); onClickToClose(); }; useEffect(() => { - setFilterDisbursementStatus(disbursementStatus); - }, [disbursementStatus]); + setFilterStatus(status); + }, [status]); return ( <> @@ -123,9 +123,9 @@ export const PayoutFilter = ({ > { setNextCursor(null); } }); - callBalance(); }; @@ -177,18 +176,19 @@ export const FundAccountTransferListWrap = () => { date = itemDate; } if (date !== itemDate) { - date = itemDate; + // 날짜가 바뀌면 이전 리스트를 푸시 (날짜 업데이트 전에!) if (list.length > 0) { rs.push( ); } + date = itemDate; // 그 다음에 날짜 업데이트 list = []; } list.push(listItems[i] as any); diff --git a/src/entities/additional-service/ui/info-wrap/payment-info-wrap.tsx b/src/entities/additional-service/ui/info-wrap/payment-info-wrap.tsx index bfc0419..77cea24 100644 --- a/src/entities/additional-service/ui/info-wrap/payment-info-wrap.tsx +++ b/src/entities/additional-service/ui/info-wrap/payment-info-wrap.tsx @@ -1,7 +1,7 @@ import moment from 'moment'; import { AdditionalServiceCategory, DetailInfoSectionProps } from '../../model/types'; -import { getPaymentStatusText, getSendMethodText } from '../../lib/payment-status-utils'; +import { getPaymentStatusText, getProcessStatusText, getSendMethodText } from '../../lib/payment-status-utils'; export const PaymentInfoWrap = ({ additionalServiceCategory, @@ -28,7 +28,7 @@ export const PaymentInfoWrap = ({
  • 발송일자 - {paymentInfo?.sendDate && moment(paymentInfo.sendDate).format('YYYY.MM.DD')} + {paymentInfo?.sendDate && moment(paymentInfo?.sendDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD')}
  • @@ -56,7 +56,7 @@ export const PaymentInfoWrap = ({ <>
  • 진행상태 - {paymentInfo?.processStatus} + {getProcessStatusText(paymentInfo?.processStatus)}
  • 요청일자 @@ -65,7 +65,7 @@ export const PaymentInfoWrap = ({
  • 결제유효일자 - {paymentInfo?.paymentLimitDate && moment(paymentInfo.paymentLimitDate).format('YYYY.MM.DD')} + {paymentInfo?.paymentLimitDate && moment(paymentInfo.paymentLimitDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD')}
  • diff --git a/src/entities/additional-service/ui/info-wrap/title-info-wrap.tsx b/src/entities/additional-service/ui/info-wrap/title-info-wrap.tsx index 7d3b2a0..9b9523c 100644 --- a/src/entities/additional-service/ui/info-wrap/title-info-wrap.tsx +++ b/src/entities/additional-service/ui/info-wrap/title-info-wrap.tsx @@ -54,7 +54,7 @@ export const TitleInfoWrap = ({
    {titleInfo?.corpName}
    -
    {titleInfo?.sendDate && moment(titleInfo.sendDate).format('YYYY.MM.DD')}
    +
    {titleInfo?.sendDate && moment(titleInfo.sendDate,'YYYYMMDDHHmmss').format('YYYY.MM.DD')}
    )} {/*링크결제_발송대기*/} diff --git a/src/entities/additional-service/ui/link-payment/apply/link-payment-step1.tsx b/src/entities/additional-service/ui/link-payment/apply/link-payment-step1.tsx index 28a2e63..2c5c5e8 100644 --- a/src/entities/additional-service/ui/link-payment/apply/link-payment-step1.tsx +++ b/src/entities/additional-service/ui/link-payment/apply/link-payment-step1.tsx @@ -13,7 +13,7 @@ export const LinkPaymentStep1 = ({ formData, setFormData }: LinkPaymentStep1Prop const { navigate } = useNavigate(); useSetOnBack(() => { - navigate(PATHS.additionalService.list); + navigate(PATHS.additionalService.linkPayment.shippingHistory); }); const handlePaymentMethodChange = (method: LinkPaymentSendMethod) => { @@ -24,8 +24,16 @@ export const LinkPaymentStep1 = ({ formData, setFormData }: LinkPaymentStep1Prop setFormData({ ...formData, [field]: value }); }; + const handleAmountChange = (value: string) => { + // 숫자만 추출 + const onlyNumbers = value.replace(/[^0-9]/g, ''); + // 빈 문자열이면 0, 아니면 숫자로 변환 (앞의 0 제거됨) + const numericValue = onlyNumbers === '' ? 0 : parseInt(onlyNumbers, 10); + setFormData({ ...formData, amount: numericValue }); + }; + const handleDateChange = (date: string) => { - setFormData({ ...formData, paymentExpiryDate: date }); + setFormData({ ...formData, paymentLimitDate: date }); }; return ( @@ -87,9 +95,11 @@ export const LinkPaymentStep1 = ({ formData, setFormData }: LinkPaymentStep1Prop
    handleInputChange('amount', e.target.value)} + placeholder="0" + value={formData.amount === 0 ? '' : formData.amount} + onChange={(e) => handleAmountChange(e.target.value)} + inputMode="numeric" + pattern="[0-9]*" />
    @@ -111,9 +121,10 @@ export const LinkPaymentStep1 = ({ formData, setFormData }: LinkPaymentStep1Prop
    까지
    diff --git a/src/entities/additional-service/ui/link-payment/filter/link-payment-history-filter.tsx b/src/entities/additional-service/ui/link-payment/filter/link-payment-history-filter.tsx index e96bfc4..0402462 100644 --- a/src/entities/additional-service/ui/link-payment/filter/link-payment-history-filter.tsx +++ b/src/entities/additional-service/ui/link-payment/filter/link-payment-history-filter.tsx @@ -13,7 +13,7 @@ import { FilterCalendar } from '@/shared/ui/filter/calendar'; import { FilterButtonGroups } from '@/shared/ui/filter/button-groups'; import { FilterMotionDuration, FilterMotionStyle, FilterMotionVariants } from '@/entities/common/model/constant'; import { useStore } from '@/shared/model/store'; -import { LinkPaymentHistoryFilterProps, LinkPaymentPaymentStatus, LinkPaymentSearchCl, LinkPaymentSendMethod } from '@/entities/additional-service/model/link-pay/types'; +import { LinkPaymentHistoryFilterProps, LinkPaymentPaymentStatus, LinkPaymentSearchCl, LinkPaymentSendMethod, LinkPaymentSendStatus } from '@/entities/additional-service/model/link-pay/types'; export const LinkPaymentHistoryFilter = ({ filterOn, @@ -24,53 +24,31 @@ export const LinkPaymentHistoryFilter = ({ fromDate, toDate, paymentStatus, - processResult, + sendStatus, sendMethod, setMid, setSearchType, setSearchKeyword, setStartDate, setEndDate, - setTransactionStatus, - setProcessResult, + setPaymentStatus, + setSendStatus, setSendMethod }: LinkPaymentHistoryFilterProps) => { const [filterMid, setFilterMid] = useState(mid); - const [filterSearchType, setFilterSearchType] = useState(searchCl); - const [filterSearchKeyword, setFilterSearchKeyword] = useState(searchValue); + const [filterSearchCl, setFilterSearchCl] = useState(searchCl); + const [filterSearchValue, setFilterSearchValue] = useState(searchValue); const [filterStartDate, setFilterStartDate] = useState(fromDate); const [filterEndDate, setFilterEndDate] = useState(toDate); const [filterTransactionStatus, setFilterTransactionStatus] = useState(paymentStatus) - const [filterProcessResult, setFilterProcessResult] = useState(processResult); + const [filterSendStatus, setFilterSendStatus] = useState(sendStatus); const [filterSendMethod, setFilterSendMethod] = useState(sendMethod); - const [dateReadOnly, setDateReadyOnly] = useState(true); - const [filterDateOptionsBtn, setFilterDateOptionsBtn] = useState(FilterDateOptions.Input); const [calendarOpen, setCalendarOpen] = useState(false); const midOptions = useStore.getState().UserStore.selectOptionsMids; - - const onClickToClose = () => { - setFilterOn(false); - }; - - const setNewDate = (newDate: any) => { - console.log(newDate) - }; - - const onClickToSetFilter = () => { - setMid(filterMid); - setSearchType(filterSearchType); - setSearchKeyword(filterSearchKeyword); - setStartDate(filterStartDate); - setEndDate(filterEndDate); - setTransactionStatus(filterTransactionStatus); - setProcessResult(filterProcessResult); - setSendMethod(filterSendMethod); - onClickToClose(); - }; let searchTypeOption = [ { name: '휴대폰번호', value: LinkPaymentSearchCl.PHONE }, @@ -87,9 +65,9 @@ export const LinkPaymentHistoryFilter = ({ ]; let processResultOption = [ - { name: '전체', value: ProcessResult.ALL }, - { name: '성공', value: ProcessResult.SUCCESS }, - { name: '실패', value: ProcessResult.FAIL }, + { name: '전체', value: LinkPaymentSendStatus.ALL }, + { name: '성공', value: LinkPaymentSendStatus.SUCCESS }, + { name: '실패', value: LinkPaymentSendStatus.FAIL }, ]; let sendMethodOption = [ @@ -99,15 +77,35 @@ export const LinkPaymentHistoryFilter = ({ { name: '카카오', value: LinkPaymentSendMethod.KAKAO }, ]; + const onClickToClose = () => { + setFilterOn(false); + }; + + const onClickToSetFilter = () => { + setMid(filterMid); + setSearchType(filterSearchCl); + setSearchKeyword(filterSearchValue); + setStartDate(filterStartDate); + setEndDate(filterEndDate); + setPaymentStatus(filterTransactionStatus); + setSendStatus(filterSendStatus); + setSendMethod(filterSendMethod); + onClickToClose(); + }; + + useEffect(() => { + + }) + return ( <>
    @@ -136,8 +134,8 @@ export const LinkPaymentHistoryFilter = ({ { @@ -38,7 +38,7 @@ export const LinkPaymentWaitSendFilter = ({ const [filterStartDate, setFilterStartDate] = useState(startDate); const [filterEndDate, setFilterEndDate] = useState(endDate); const [filterSendMethod, setFilterSendMethod] = useState(sendMethod) - const [filterSendingStatus, setFilterSendingStatus] = useState(sendingStatus); + const [filterProcessStatus, setFilterProcessStatus] = useState(processStatus); const [dateReadOnly, setDateReadyOnly] = useState(true); const [filterDateOptionsBtn, setFilterDateOptionsBtn] = useState(FilterDateOptions.Input); @@ -61,7 +61,7 @@ export const LinkPaymentWaitSendFilter = ({ setStartDate(filterStartDate); setEndDate(filterEndDate); setSendMethod(filterSendMethod); - setSendingStatus(filterSendingStatus); + setProcessStatus(filterProcessStatus); onClickToClose(); }; @@ -77,10 +77,10 @@ export const LinkPaymentWaitSendFilter = ({ { name: '카카오', value: LinkPaymentSendMethod.KAKAO }, ]; - let sendingStatusOption = [ - { name: '전체', value: LinkPaymentSendStatus.ALL }, - { name: '발송요청', value: LinkPaymentSendStatus.SUCCESS }, - { name: '발송취소', value: LinkPaymentSendStatus.FAIL }, + let processStatusOption = [ + { name: '전체', value: LinkPaymentProcessStatus.ALL }, + { name: '발송요청', value: LinkPaymentProcessStatus.SEND_REQUEST }, + { name: '발송취소', value: LinkPaymentProcessStatus.SEND_CANCEL }, ]; return ( @@ -142,9 +142,9 @@ export const LinkPaymentWaitSendFilter = ({
    diff --git a/src/entities/additional-service/ui/link-payment/link-payment-history-list.tsx b/src/entities/additional-service/ui/link-payment/link-payment-history-list.tsx index 7266df0..c21559b 100644 --- a/src/entities/additional-service/ui/link-payment/link-payment-history-list.tsx +++ b/src/entities/additional-service/ui/link-payment/link-payment-history-list.tsx @@ -1,20 +1,50 @@ -import { LinkPaymentHistoryListProps } from '../../model/link-pay/types'; +import { JSX } from 'react'; +import { LinkPaymentHistoryListItem, LinkPaymentHistoryListProps } from '../../model/link-pay/types'; import { ListDateGroup } from '../list-date-group'; export const LinkPaymentHistoryList = ({ additionalServiceCategory, - listItems + listItems, + setTarget, + mid }: LinkPaymentHistoryListProps) => { const getListDateGroup = () => { - let rs = []; - for (const [key, value] of Object.entries(listItems)) { + let rs: JSX.Element[] = []; + let date = ''; + let list: LinkPaymentHistoryListItem[] = []; + for (let i = 0; i < listItems.length; i++) { + // paymentDate format: "20211018140420" (YYYYMMDDHHmmss) + let sendDate = listItems[i]?.sendDate || ''; + let itemDate = sendDate.substring(0, 8); + if (i === 0) { + date = itemDate; + } + if (date !== itemDate) { + if (list.length > 0) { + rs.push( + + ); + } + date = itemDate; + list = []; + } + list.push(listItems[i] as any); + } + if (list.length > 0) { rs.push( ); } @@ -25,6 +55,7 @@ export const LinkPaymentHistoryList = ({ <>
    {getListDateGroup()} +
    ) diff --git a/src/entities/additional-service/ui/link-payment/link-payment-history-wrap.tsx b/src/entities/additional-service/ui/link-payment/link-payment-history-wrap.tsx index 96ba439..de4e77f 100644 --- a/src/entities/additional-service/ui/link-payment/link-payment-history-wrap.tsx +++ b/src/entities/additional-service/ui/link-payment/link-payment-history-wrap.tsx @@ -6,37 +6,64 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { PATHS } from "@/shared/constants/paths"; import { LinkPaymentHistoryList } from "./link-payment-history-list"; import { SortTypeBox } from '@/entities/common/ui/sort-type-box'; -import { SortTypeKeys } from '@/entities/common/model/types'; +import { DefaultRequestPagination, SortTypeKeys } from '@/entities/common/model/types'; import { AdditionalServiceCategory, ProcessResult } from "../../model/types"; import { useExtensionLinkPayHistoryListMutation } from '../../api/link-payment/use-extension-link-pay-history-list-mutation'; import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant'; import { useExtensionLinkPayHistoryDownloadExcelMutation } from '../../api/link-payment/use-extension-link-pay-history-download-excel-mutation'; import { useStore } from '@/shared/model/store'; -import { LinkPaymentHistoryListItem, LinkPaymentPaymentStatus, LinkPaymentSearchCl, LinkPaymentSendMethod } from '../../model/link-pay/types'; +import { ExtensionLinkPayHistoryListParams, LinkPaymentHistoryListItem, LinkPaymentPaymentMethod, LinkPaymentPaymentStatus, LinkPaymentSearchCl, LinkPaymentSendMethod, LinkPaymentSendStatus } from '../../model/link-pay/types'; +import useIntersectionObserver from '@/widgets/intersection-observer'; -const processResultBtnGroup = [ - { name: '전체', value: ProcessResult.ALL }, - { name: '성공', value: ProcessResult.SUCCESS }, - { name: '실패', value: ProcessResult.FAIL } +const paymentResultBtnGroup = [ + { name: '전체', value: LinkPaymentPaymentStatus.ALL }, + { name: '미완료/활성화', value: LinkPaymentPaymentStatus.ACTIVATE }, + { name: '입금요청', value: LinkPaymentPaymentStatus.DEPOSIT_REQUEST }, + { name: '결제완료', value: LinkPaymentPaymentStatus.PAYMENT_COMPLETE }, + { name: '결제실패', value: LinkPaymentPaymentStatus.PAYMENT_FAIL }, + { name: '결제중단/비활성화', value: LinkPaymentPaymentStatus.INACTIVE }, ]; export const LinkPaymentHistoryWrap = () => { const { navigate } = useNavigate(); const userMid = useStore.getState().UserStore.mid; + const [onActionIntersect, setOnActionIntersect] = useState(false); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + entries.forEach((entry: IntersectionObserverEntry) => { + if (entry.isIntersecting) { + console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); + if (onActionIntersect) { + callList(); + } + } + else { + console.log('Element is no longer intersecting with the root.'); + } + }); + }; + + const { setTarget } = useIntersectionObserver({ + threshold: 1, + onIntersect + }); const [filterOn, setFilterOn] = useState(false); const [sortType, setSortType] = useState(SortTypeKeys.LATEST); - const [listItems, setListItems] = useState({}); - const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); + const [listItems, setListItems] = useState>([]); + const [nextCursor, setNextCursor] = useState(null); + const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); const [mid, setMid] = useState(userMid); - const [searchCl, setSearchCl] = useState(LinkPaymentSearchCl.ALL) - const [searchKeyword, setSearchKeyword] = useState(''); - const [startDate, setStartDate] = useState(moment().format('YYYY-MM-DD')); - const [endDate, setEndDate] = useState(moment().format('YYYY-MM-DD')); - const [transactionStatus, setTransactionStatus] = useState(LinkPaymentPaymentStatus.ALL) - const [processResult, setProcessResult] = useState(ProcessResult.ALL) - const [sendMethod, setSendMethod] = useState(LinkPaymentSendMethod.ALL) + const [searchCl, setSearchCl] = useState(LinkPaymentSearchCl.PHONE); + const [searchValue, setSearchValue] = useState(''); + const [paymentMethod, setPaymentMethod] = useState(LinkPaymentPaymentMethod.CARD); + const [fromDate, setFromDate] = useState(moment().format('YYYYMMDD')); + const [toDate, setToDate] = useState(moment().format('YYYYMMDD')); + const [paymentStatus, setPaymentStatus] = useState(LinkPaymentPaymentStatus.ALL); + const [sendStatus, setSendStatus] = useState(LinkPaymentSendStatus.ALL); + const [sendMethod, setSendMethod] = useState(LinkPaymentSendMethod.ALL); + + const [email, setEmail] = useState(''); const { mutateAsync: linkPayHistoryList } = useExtensionLinkPayHistoryListMutation(); const { mutateAsync: downloadExcel } = useExtensionLinkPayHistoryDownloadExcelMutation(); @@ -47,71 +74,80 @@ export const LinkPaymentHistoryWrap = () => { const callList = (option?: { sortType?: SortTypeKeys, - val?: string + status?: LinkPaymentPaymentStatus, + resetPage?: boolean }) => { - pageParam.sortType = (option?.sortType) ? option.sortType : sortType; - setPageParam(pageParam); + setOnActionIntersect(false); - let listParams = { + const currentPageParam = option?.resetPage + ? { ...DEFAULT_PAGE_PARAM, sortType: option?.sortType ?? sortType } + : { ...pageParam, sortType: option?.sortType ?? sortType }; + + setPageParam(currentPageParam); // currentPageParam으로 수정! + + let listParams: ExtensionLinkPayHistoryListParams = { mid: mid, searchCl: searchCl, - searchValue: searchKeyword, - paymentMethod: '', - fromDate: startDate, - toDate: endDate, - paymentStatus: transactionStatus === LinkPaymentPaymentStatus.ALL ? '' : transactionStatus, - sendStatus: processResult === ProcessResult.ALL ? '' : processResult, - sendMethod: sendMethod === LinkPaymentSendMethod.ALL ? '' : sendMethod, - page: pageParam + searchValue: searchValue, + fromDate: fromDate, + toDate: toDate, + paymentStatus: option?.status ?? paymentStatus, + sendStatus: sendStatus, + sendMethod: sendMethod, + ... { + page: currentPageParam + } }; linkPayHistoryList(listParams).then((rs) => { - setListItems(assembleData(rs.content)); - }); - }; - - const assembleData = (content: Array) => { - let data: any = {}; - if(content && content.length > 0){ - for(let i=0;i { downloadExcel({ mid: mid, + email: email, searchCl: searchCl, - searchValue: searchKeyword, - paymentMethod: '', - fromDate: startDate, - toDate: endDate, - paymentStatus: transactionStatus, - sendStatus: (processResult === ProcessResult.ALL)? '': processResult, - sendMethod: (sendMethod === LinkPaymentSendMethod.ALL)? '': sendMethod, + searchValue: searchValue, + paymentMethod: paymentMethod, + fromDate: fromDate, + toDate: toDate, + paymentStatus: paymentStatus, + sendStatus: sendStatus, + sendMethod: sendMethod, }).then((rs) => { console.log('Excel Dowload Status : ' + rs.status); }); }; - const onClickProcessResult = (val: ProcessResult) => { - setProcessResult(val); + const onClickPaymentStatus = (val: LinkPaymentPaymentStatus) => { + setPaymentStatus(val); + callList({ + status: val, + resetPage: true + }) } const onClickToSort = (sort: SortTypeKeys) => { setSortType(sort); callList({ - sortType: sort + sortType: sort, + resetPage: true }); }; @@ -120,8 +156,19 @@ export const LinkPaymentHistoryWrap = () => { }; useEffect(() => { - callList(); - }, []); + // 필터 조건이 변경되면 첫 페이지부터 다시 시작 + callList({ resetPage: true }); + }, [ + mid, + searchCl, + searchValue, + paymentMethod, + fromDate, + toDate, + paymentStatus, + sendStatus, + sendMethod + ]); return ( <> @@ -131,7 +178,7 @@ export const LinkPaymentHistoryWrap = () => {
    } @@ -101,11 +146,12 @@ export const LinkPaymentApplyPage = () => {
    + onClick={() => onClickToBack()} + >이전
    } diff --git a/src/pages/additional-service/link-payment/link-payment-detail-page.tsx b/src/pages/additional-service/link-payment/link-payment-detail-page.tsx index a1de129..d776d36 100644 --- a/src/pages/additional-service/link-payment/link-payment-detail-page.tsx +++ b/src/pages/additional-service/link-payment/link-payment-detail-page.tsx @@ -18,12 +18,13 @@ import { PaymentInfoWrap } from '@/entities/additional-service/ui/info-wrap/paym import { DetailInfoWrap } from '@/entities/additional-service/ui/info-wrap/detail-info-wrap'; import { useExtensionLinkPayHistoryResendMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-history-resend-mutation'; import { ExtensionLinkPayHistoryDetailParams, ExtensionLinkPayHistoryResendParams } from '@/entities/additional-service/model/link-pay/types'; +import moment from 'moment'; export const LinkPaymentDetailPage = () => { const { navigate } = useNavigate(); const location = useLocation(); - const { mid, tid } = location.state || {}; + const { mid, tid, requestId, subReqId } = location.state || {}; const [titleInfo, setTitleInfo] = useState(); const [detailInfo, setDetailInfo] = useState(); @@ -34,16 +35,19 @@ export const LinkPaymentDetailPage = () => { useSetHeaderTitle('링크결제 상세'); useSetHeaderType(HeaderType.RightClose); useSetOnBack(() => { - navigate(PATHS.additionalService.linkPayment.shippingHistory); + navigate(-1); // 브라우저 히스토리를 이용한 뒤로가기 }); useSetFooterMode(false); const { mutateAsync: linkPayHistoryDetail } = useExtensionLinkPayHistoryDetailMutation(); const { mutateAsync: linkPayHistoryResend } = useExtensionLinkPayHistoryResendMutation(); + + // 상세내역 조회 const callDetail = () => { let detailParam: ExtensionLinkPayHistoryDetailParams = { mid: mid, - tid: tid + requestId: requestId, + subReqId: subReqId } linkPayHistoryDetail(detailParam).then((rs: DetailResponse) => { console.log("Detail Info: ", rs) @@ -53,15 +57,18 @@ export const LinkPaymentDetailPage = () => { }) } + //제발송 API const resendPayment = () => { let resendParam: ExtensionLinkPayHistoryResendParams = { mid: mid, - tid: tid + requestId: requestId, + sendMethod: paymentInfo?.sendMethod } linkPayHistoryResend(resendParam) .then((response) => { console.log("Resend 성공 응답: ", response); - onClickToNavigate(PATHS.additionalService.linkPayment.shippingHistory) + // 현재 화면 유지하고 데이터 새로고침 + callDetail(); }) .catch((error) => { console.error("Resend 실패: ", error); @@ -103,6 +110,24 @@ export const LinkPaymentDetailPage = () => { state: { mid, tid } }); }; + + // 재발송 버튼 활성화 조건 체크 + const isResendEnabled = () => { + // paymentStatus가 "ACTIVE"이고 + if (paymentInfo?.paymentStatus !== 'ACTIVE') { + return false; + } + + // paymentLimitDate가 오늘 날짜를 지나지 않았을 때 + if (paymentInfo?.paymentLimitDate) { + const limitDate = moment(paymentInfo.paymentLimitDate, 'YYYYMMDD'); + const today = moment().startOf('day'); + return limitDate.isSameOrAfter(today); + } + + return false; + }; + useEffect(() => { callDetail(); }, []); @@ -129,18 +154,19 @@ export const LinkPaymentDetailPage = () => { detailInfo={detailInfo} >
    -
    + {/*
    -
    - {/*
    +
    */} +
    -
    */} +
    diff --git a/src/pages/additional-service/link-payment/link-payment-wait-detail-page.tsx b/src/pages/additional-service/link-payment/link-payment-wait-detail-page.tsx index 92156c7..1dda617 100644 --- a/src/pages/additional-service/link-payment/link-payment-wait-detail-page.tsx +++ b/src/pages/additional-service/link-payment/link-payment-wait-detail-page.tsx @@ -21,7 +21,7 @@ import { ExtensionLinkPayWaitDeleteParams, ExtensionLinkPayWaitDetailParams } fr export const LinkPaymentWaitDetailPage = () => { const { navigate } = useNavigate(); const location = useLocation(); - const { mid, tid } = location.state || {}; + const { mid, requestId } = location.state || {}; const [titleInfo, setTitleInfo] = useState(); const [paymentInfo, setPaymentInfo] = useState(); @@ -34,10 +34,11 @@ export const LinkPaymentWaitDetailPage = () => { const { mutateAsync: linkPayWaitDetail } = useExtensionLinkPayWaitDetailMutation(); const { mutateAsync: linkPayWaitDelete } = useExtensionLinkPayWaitDeleteMutation(); + const callDetail = () => { let detailParam: ExtensionLinkPayWaitDetailParams = { mid: mid, - tid: tid + requestId: requestId } linkPayWaitDetail(detailParam).then((rs: DetailResponse) => { @@ -51,7 +52,7 @@ export const LinkPaymentWaitDetailPage = () => { const deletePayment = () => { let deleteParam: ExtensionLinkPayWaitDeleteParams = { mid: mid, - tid: tid + requestId: requestId } linkPayWaitDelete(deleteParam) .then((response) => { diff --git a/src/pages/additional-service/payout/detail-page.tsx b/src/pages/additional-service/payout/detail-page.tsx index b45b48e..89f6594 100644 --- a/src/pages/additional-service/payout/detail-page.tsx +++ b/src/pages/additional-service/payout/detail-page.tsx @@ -21,6 +21,8 @@ export const PayoutDetailPage = () => { const tid = location.state.tid; const mid = location.state.mid; + const [requestType, setRequestType] = useState(''); + const [email, setEmail] = useState(''); const [detail, setDetail] = useState(); 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 = () => { > -
    나이스테스트가맹점
    -
    2025.08.19
    +
    {detail?.companyName}
    +
    {detail?.settlementDate}
  • 지급일시 - { detail?.settlementDate } + { detail?.settlementDateTime }
  • 사업자번호 diff --git a/src/pages/additional-service/payout/list-page.tsx b/src/pages/additional-service/payout/list-page.tsx index 696389a..b4fe353 100644 --- a/src/pages/additional-service/payout/list-page.tsx +++ b/src/pages/additional-service/payout/list-page.tsx @@ -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(false); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + 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.LATEST); - const [listItems, setListItems] = useState>>({}); + const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); - const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); + const [nextCursor, setNextCursor] = useState(null); + const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); const [mid, setMid] = useState(userMid); - const [searchCl, setSearchCl] = useState(PayoutSearchCl.REQUEST_DATE); + const [searchDateType, setSearchDateType] = useState(PayoutSearchDateType.REQUEST_DATE); const [fromDate, setFromDate] = useState(moment().format('YYYYMMDD')); const [toDate, setToDate] = useState(moment().format('YYYYMMDD')); - const [disbursementStatus, setDisbursementStatus] = useState(PayoutDisbursementStatus.ALL); - const [minAmount, setMinAmount] = useState(); - const [maxAmount, setMaxAmount] = useState(); + const [status, setStatus] = useState(PayoutDisbursementStatus.ALL); + const [minAmount, setMinAmount] = useState(0); + const [maxAmount, setMaxAmount] = useState(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) => { - let data: any = {}; - if(content && content.length > 0){ - for(let i=0;i { 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( - - ); + 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( + + ); + } + date = itemDate; // 그 다음에 날짜 업데이트 + list = []; + } + list.push(listItems[i] as any); + } + if (list.length > 0) { + rs.push( + + ); } return rs; - } + }; return ( <> @@ -234,7 +288,7 @@ export const PayoutListPage = () => { PayoutDisbursementStatusBtnGroup.map((value, index) => ( onClickToDisbursementStatus(value.value) } >{ value.name } )) @@ -242,14 +296,15 @@ export const PayoutListPage = () => { -
    - { getPayoutList() } -
    - -
    +
    + { getListDateGroup() } +
    +
    +
    +
    @@ -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 } > diff --git a/src/pages/additional-service/payout/request-page.tsx b/src/pages/additional-service/payout/request-page.tsx index a23b8d9..e0b3304 100644 --- a/src/pages/additional-service/payout/request-page.tsx +++ b/src/pages/additional-service/payout/request-page.tsx @@ -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 = () => {
    -
    서브ID
    +
    서브ID*
    {
    -
    지급액
    +
    지급액*
    {
    -
    지급일
    +
    지급일*
    { className="date-btn" type="button" onClick={() => onClickToOpenCalendar()} + disabled={!isFormValid} > void; + minDate?: Date; + maxDate?: Date; }; const NiceCalendar = ({ @@ -23,7 +25,9 @@ const NiceCalendar = ({ endDate, singleDate, calendarType, - setNewDate + setNewDate, + minDate: propMinDate, + maxDate: propMaxDate }: NiceCalendarProps) => { const [valueDate, setValueDate] = useState(); const [minDate, setMinDate] = useState(); @@ -38,20 +42,22 @@ const NiceCalendar = ({ }; const setMinMaxValueDate = () => { if(calendarType === CalendarType.Start){ - setMinDate(undefined); + setMinDate(propMinDate || undefined); if(!!endDate){ setMaxDate(new Date(endDate)); } setValueDate(startDate); - } + } else if(calendarType === CalendarType.End){ if(!!startDate){ setMinDate(new Date(startDate)); } - setMaxDate(new Date()); + setMaxDate(propMaxDate || new Date()); setValueDate(endDate); } else if(calendarType === CalendarType.Single){ + setMinDate(propMinDate || undefined); + setMaxDate(propMaxDate || undefined); setValueDate(singleDate); } }; diff --git a/src/shared/ui/filter/single-date-picker.tsx b/src/shared/ui/filter/single-date-picker.tsx index e1d9045..266e496 100644 --- a/src/shared/ui/filter/single-date-picker.tsx +++ b/src/shared/ui/filter/single-date-picker.tsx @@ -8,13 +8,17 @@ interface SingleDatePickerProps { date: string; setDate: (date: string) => void; placeholder?: string; + minDate?: Date; + maxDate?: Date; } export const SingleDatePicker = ({ title, date, setDate, - placeholder = '날짜 선택' + placeholder = '날짜 선택', + minDate, + maxDate }: SingleDatePickerProps) => { const [calendarOpen, setCalendarOpen] = useState(false); @@ -84,6 +88,8 @@ export const SingleDatePicker = ({ singleDate={date} calendarType={CalendarType.Single} setNewDate={setNewDate} + minDate={minDate} + maxDate={maxDate} > );