- SMS,KeyIn,ARS 페이지 스크롤 적용

- ARS 결제신청 :성공 결과 팝업 추가
This commit is contained in:
HyeonJongKim
2025-10-20 16:03:13 +09:00
parent 5d2af3fb06
commit 948657db3f
20 changed files with 570 additions and 296 deletions

View File

@@ -22,8 +22,9 @@ export interface AccountHolderSearchListItem {
}
export interface AccountHolderSearchListProps {
listItems: Record<string, Array<ListItemProps>>;
listItems: Array<AccountHolderSearchListItem>;
mid: string;
setTarget: (element: HTMLElement | null) => void;
}
export interface AccountHolderSearchFilterProps extends FilterProps {

View File

@@ -15,4 +15,16 @@ export const ArsOrderStatusBtnGroup = [
export const ArsPaymentMethodBtnGroup = [
{name: 'SMS', value: ArsPaymentMethod.SMS },
{name: 'ARS', value: ArsPaymentMethod.ARS },
];
];
export const getArsPaymentStatusName = (status?: string): string => {
if (!status) return '';
const found = ArsPaymentStatusBtnGroup.find(item => item.value === status);
return found ? found.name : status;
}
export const getArsOrderStatusName = (status?: string): string => {
if (!status) return '';
const found = ArsOrderStatusBtnGroup.find(item => item.value === status);
return found ? found.name : status;
}

View File

@@ -4,12 +4,12 @@ import {
} from '@/entities/common/model/types';
export enum PaymentStatus {
ALL = 'ALL',
ALL = '',
COMPLETE = 'COMPLETE',
UNPAID = 'UNPAID'
};
export enum OrderStatus {
ALL = 'ALL',
ALL = '',
PENDING = 'PENDING',
SUCCESS = 'SUCCESS',
EXPIRED = 'EXPIRED',
@@ -39,8 +39,8 @@ export interface ArsListContent {
tid?: string;
paymentDate?: string;
paymentStatus?: PaymentStatus | string;
orderStatus?: string;
arsPaymentMethod?: ArsPaymentMethod;
orderStatus?: OrderStatus;
arsPaymentMethod?: string;
amount?: number;
};
export interface ExtensionArsListResponse extends DefaulResponsePagination {
@@ -64,7 +64,7 @@ export interface ExtensionArsDetailParams {
export interface ExtensionArsDetailResponse {
corpName: string;
mid: string;
arsPaymentMethod: ArsPaymentMethod;
arsPaymentMethod: string;
paymentStatus: PaymentStatus;
orderStatus: string;
paymentDate: string;
@@ -85,6 +85,6 @@ export interface ExtensionArsApplyParams {
buyerName: string;
phoneNumber: string;
email: string;
arsPaymentMethod: ArsPaymentMethod;
arsPaymentMethod: string;
};
export interface ExtensionArsApplyResponse {};

View File

@@ -1,9 +1,15 @@
import { KeyInPaymentPaymentStatus } from "./types";
// contant로 옮기기
export const requestStatusBtnGroup = [
export const keyInPaymentPaymentStatusBtnGroup = [
{ name: '전체', value: KeyInPaymentPaymentStatus.ALL },
{ name: '승인', value: KeyInPaymentPaymentStatus.APPROVAL },
{ name: '전취소', value: KeyInPaymentPaymentStatus.PRE_CANCEL },
{ name: '후취소', value: KeyInPaymentPaymentStatus.POST_CANCEL }
];
];
export const getKeyInPaymentPaymentStatusName = (status?: string): string => {
if (!status) return '';
const found = keyInPaymentPaymentStatusBtnGroup.find(item => item.value === status);
return found ? found.name : status;
}

View File

@@ -0,0 +1,13 @@
import { SmsCl } from './types';
export const SmsClBtnGroup = [
{ name: '', value: SmsCl.ALL },
{ name: '가상계좌 요청', value: SmsCl.VACCOUNT_REQ },
{ name: '가상계좌 요청 + 입금', value: SmsCl.VACCOUNT_REQ_DEPOSIT }
];
export const getSmsClName = (smsCl?: string): string => {
if (!smsCl) return '';
const found = SmsClBtnGroup.find(item => item.value === smsCl);
return found ? found.name : smsCl;
};

View File

@@ -1,73 +1,75 @@
import { DefaulResponsePagination, DefaultRequestPagination } from '@/entities/common/model/types';
import { ExtensionRequestParams, FilterProps, ListItemProps } from '../types';
import { AdditionalServiceCategory, ExtensionRequestParams, FilterProps, ListItemProps } from '../types';
export enum SmsType {
ALL = "ALL",
VACCOUNT_REQ = "VACCOUNT_REQ",
VACCOUNT_REQ_DEPOSIT = "VACCOUNT_REQ_DEPOSIT"
export enum SmsCl {
ALL = "",
VACCOUNT_REQ = "VACCOUNT_REQ",
VACCOUNT_REQ_DEPOSIT = "VACCOUNT_REQ_DEPOSIT"
}
export enum SmsPaymentSearchType {
BUYER_NAME = "BUYER_NAME",
RECEIVE_PHONE_NUMBER = "RECEIVE_PHONE_NUMBER"
export enum SmsPaymentSearchCl {
BUYER_NAME = "BUYER_NAME",
RECEIVE_PHONE_NUMBER = "RECEIVE_PHONE_NUMBER"
}
export interface SmsPaymentListItem {
mid?: string;
tid?: string;
paymentDate?: string;
paymentStatus?: string;
smsCl?: string;
mid?: string;
tid?: string;
paymentDate?: string;
paymentStatus?: string;
smsCl?: string;
}
export interface SmsPaymentListProps {
listItems: Record<string, Array<ListItemProps>>;
mid: string;
onResendClick?: (mid: string, tid: string) => void;
listItems: Array<ListItemProps>;
additionalServiceCategory: AdditionalServiceCategory;
mid: string;
onResendClick?: (mid: string, tid: string) => void;
setTarget: (element: HTMLElement | null) => void;
}
export interface SmsPaymentFilterProps extends FilterProps {
mid: string;
searchCl: SmsPaymentSearchType;
searchValue: string;
fromDate: string;
toDate: string;
smsCl: SmsType;
setMid: (mid: string) => void;
setSearchCl: (searchCl: SmsPaymentSearchType) => void;
setSearchValue: (searchValue: string) => void;
setFromDate: (fromDate: string) => void;
setToDate: (toDate: string) => void;
setSmsCl: (smsCl: SmsType) => void;
mid: string;
searchCl: SmsPaymentSearchCl;
searchValue: string;
fromDate: string;
toDate: string;
smsCl: SmsCl;
setMid: (mid: string) => void;
setSearchCl: (searchCl: SmsPaymentSearchCl) => void;
setSearchValue: (searchValue: string) => void;
setFromDate: (fromDate: string) => void;
setToDate: (toDate: string) => void;
setSmsCl: (smsCl: SmsCl) => void;
}
export interface ExtensionSmsPaymentListParams extends ExtensionRequestParams {
searchCl: SmsPaymentSearchType;
searchValue: string;
fromDate: string;
toDate: string;
smsCl: string;
page?: DefaultRequestPagination;
searchCl: SmsPaymentSearchCl;
searchValue: string;
fromDate: string;
toDate: string;
smsCl: SmsCl;
page?: DefaultRequestPagination;
}
export interface ExtensionSmsPaymentListResponse extends DefaulResponsePagination {
content: Array<ListItemProps>
content: Array<ListItemProps>
}
export interface ExtensionSmsDownloadExcelResponse {
status: boolean;
status: boolean;
}
export interface ExtensionSmsDetailResponse {
senderNumber: string;
senderName: string;
receiverNumber: string;
receiverName: string;
sendMessage: string;
senderNumber: string;
senderName: string;
receiverNumber: string;
receiverName: string;
sendMessage: string;
}
export interface ExtensionSmsResendParams extends ExtensionRequestParams {
tid: string;
tid: string;
}
@@ -86,7 +88,7 @@ export interface ExtensionSmsResendParams extends ExtensionRequestParams {
}
export interface ExtensionSmsResendResponse {
status: boolean;
status: boolean;
}
export interface ExtensionSmsListParams extends ExtensionRequestParams {

View File

@@ -2,24 +2,53 @@ import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ListDateGroup } from '../list-date-group';
import { AdditionalServiceCategory } from '../../model/types'
import { AccountHolderSearchListProps } from '../../model/account-holder-search/types';
import { AccountHolderSearchListItem, AccountHolderSearchListProps } from '../../model/account-holder-search/types';
import { JSX } from 'react';
export const AccountHolderSearchList = ({
listItems,
mid
mid,
setTarget
}: AccountHolderSearchListProps) => {
const { navigate } = useNavigate();
const getListDateGroup = () => {
let rs = [];
for (const [key, value] of Object.entries(listItems)) {
let rs: JSX.Element[] = [];
let date = '';
let list: AccountHolderSearchListItem[] = [];
for (let i = 0; i < listItems.length; i++) {
// requestDate format: "20211018140420" (YYYYMMDDHHmmss)
let requestDate = listItems[i]?.requestDate || '';
let itemDate = requestDate.substring(0, 8);
if (i === 0) {
date = itemDate;
}
if (date !== itemDate) {
// 날짜가 바뀌면 이전 리스트를 푸시 (날짜 업데이트 전에!)
if (list.length > 0) {
rs.push(
<ListDateGroup
additionalServiceCategory={AdditionalServiceCategory.AccountHolderSearch}
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.AccountHolderSearch}
key={key}
date={key}
items={value}
mid={mid}
key={date + '-last'}
date={date}
items={list as any}
></ListDateGroup>
);
}
@@ -32,14 +61,15 @@ export const AccountHolderSearchList = ({
return (
<>
<div className="transaction-list">
<section className="transaction-list">
{getListDateGroup()}
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={() => onClickToNavigate()}
> </button>
</div>
<div ref={setTarget}></div>
</section>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={() => onClickToNavigate()}
> </button>
</div>
</>
);

View File

@@ -158,7 +158,6 @@ export const FundAccountResultListWrap = () => {
const onClickToSort = (sort: SortTypeKeys) => {
setSortType(sort);
setListItems([]); // 리스트 초기화
callList({
sortType: sort,
resetPage: true
@@ -166,7 +165,6 @@ export const FundAccountResultListWrap = () => {
};
const onClickToStatus = (val: FundAccountResultStatus) => {
setResultStatus(val);
setListItems([]); // 리스트 초기화
callList({
resultStatus: val,
resetPage: true
@@ -222,8 +220,6 @@ export const FundAccountResultListWrap = () => {
useEffect(() => {
// 필터 조건이 변경되면 첫 페이지부터 다시 시작
setListItems([]);
setNextCursor(null);
callList({ resetPage: true });
}, [
mid,

View File

@@ -99,7 +99,6 @@ export const FundAccountTransferListWrap = () => {
};
extensionFundAccountTransferList(listSummaryParams).then((rs: any) => {
// resetPage면 기존 리스트 무시, 아니면 추가
setListItems(option?.resetPage ? rs.content : [
...listItems,
...rs.content
@@ -152,12 +151,14 @@ export const FundAccountTransferListWrap = () => {
const onClickToSort = (sort: SortTypeKeys) => {
setSortType(sort);
setListItems([]); // 리스트 초기화
callList({ sortType: sort, resetPage: true });
callList({
sortType: sort,
resetPage: true
});
};
const onClickToStatus = (val: FundAccountStatus) => {
setStatus(val);
setListItems([]); // 리스트 초기화
callList({
status: val,
resetPage: true
@@ -208,8 +209,6 @@ export const FundAccountTransferListWrap = () => {
useEffect(() => {
// 필터 조건이 변경되면 첫 페이지부터 다시 시작
setListItems([]);
setNextCursor(null);
callList({ resetPage: true });
}, [
mid,

View File

@@ -1,16 +1,15 @@
import moment from 'moment';
import { useEffect } from 'react';
import { useState } from 'react';
import { motion } from 'framer-motion';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { FilterSelect } from '@/shared/ui/filter/select';
import { FilterSelectInput } from '@/shared/ui/filter/select-input';
import { FilterCalendar } from '@/shared/ui/filter/calendar';
import { FilterButtonGroups } from '@/shared/ui/filter/button-groups';
import { FilterRangeAmount } from '@/shared/ui/filter/range-amount';
import { FilterMotionDuration, FilterMotionStyle, FilterMotionVariants } from '@/entities/common/model/constant';
import { useStore } from '@/shared/model/store';
import { KeyInPaymentFilterProps, KeyInPaymentPaymentStatus } from '@/entities/additional-service/model/key-in/types';
import { keyInPaymentPaymentStatusBtnGroup } from '@/entities/additional-service/model/key-in/constant';
export const KeyInPaymentFilter = ({
filterOn,
@@ -42,10 +41,6 @@ export const KeyInPaymentFilter = ({
setFilterOn(false);
};
const setNewDate = (newDate: any) => {
console.log(newDate)
};
const onClickToSetFilter = () => {
setMid(filterMid);
setStartDate(filterStartDate);
@@ -55,13 +50,6 @@ export const KeyInPaymentFilter = ({
setMaxAmount(filterMaxAmount);
onClickToClose();
};
let transactionStatusOption = [
{ name: '전체', value: KeyInPaymentPaymentStatus.ALL },
{ name: '승인', value: KeyInPaymentPaymentStatus.APPROVAL },
{ name: '전취소', value: KeyInPaymentPaymentStatus.PRE_CANCEL },
{ name: '후취소', value: KeyInPaymentPaymentStatus.POST_CANCEL },
];
return (
<>
@@ -94,7 +82,7 @@ export const KeyInPaymentFilter = ({
<FilterSelect
title='가맹점'
selectValue={filterMid}
selectSetter={setMid}
selectSetter={setFilterMid}
selectOptions={midOptions}
></FilterSelect>
<FilterCalendar
@@ -108,7 +96,7 @@ export const KeyInPaymentFilter = ({
<FilterButtonGroups
title='거래상태'
activeValue={filterTransactionStatus}
btnGroups={transactionStatusOption}
btnGroups={keyInPaymentPaymentStatusBtnGroup}
setter={setFilterTransactionStatus}
></FilterButtonGroups>

View File

@@ -6,6 +6,9 @@ import { getPaymentStatusText, getProcessStatusText, getSendMethodText } from '.
import { getFundAccountResultStatusName, getFundAccountStatusName } from '../model/fund-account/constant';
import moment from 'moment';
import { FundAccountResultStatus } from '../model/fund-account/types';
import { getSmsClName } from '../model/sms-payment/constant';
import { getKeyInPaymentPaymentStatusName } from '../model/key-in/constant';
import { getArsPaymentStatusName, getArsOrderStatusName } from '../model/ars/constant';
export const ListItem = ({
additionalServiceCategory,
@@ -291,6 +294,16 @@ export const ListItem = ({
else if (additionalServiceCategory === AdditionalServiceCategory.FaceAuth) {
statusText = status || '';
}
else if (additionalServiceCategory === AdditionalServiceCategory.SMSPayment) {
console.log(smsCl)
statusText = getSmsClName(smsCl);
}
else if (additionalServiceCategory === AdditionalServiceCategory.KeyInPayment) {
statusText = getKeyInPaymentPaymentStatusName(paymentStatus)
}
else if (additionalServiceCategory === AdditionalServiceCategory.Ars) {
statusText = getArsPaymentStatusName(paymentStatus)
}
else {
statusText = resultStatus || status || '';
}
@@ -348,7 +361,7 @@ export const ListItem = ({
<div key='key-in-list' className="transaction-details">
<span>{getTime()}</span>
<span className="separator">|</span>
<span>{paymentStatus}</span>
<span>{getStatus()}</span>
</div>
);
}
@@ -451,9 +464,9 @@ export const ListItem = ({
<div className="transaction-details">
<span>{getTime()}</span>
<span className="separator">|</span>
<span>{paymentStatus}</span>
<span>{getStatus()}</span>
<span className="separator">|</span>
<span>{orderStatus}</span>
<span>{getArsOrderStatusName(orderStatus)}</span>
<span className="separator">|</span>
<span>{arsPaymentMethod}</span>
</div>
@@ -475,7 +488,7 @@ export const ListItem = ({
<div key="sms-payment" className="transaction-details">
<span>{mid}</span>
<span className="separator">|</span>
<span>{smsCl}</span>
<span>{getStatus()}</span>
</div>
)
}

View File

@@ -7,7 +7,7 @@ import { FilterSelectInput } from '@/shared/ui/filter/select-input';
import { FilterDateOptions } from '@/entities/common/model/types';
import { FilterCalendar } from '@/shared/ui/filter/calendar';
import { FilterButtonGroups } from '@/shared/ui/filter/button-groups';
import { SmsPaymentFilterProps, SmsPaymentSearchType, SmsType } from '../../model/sms-payment/types';
import { SmsPaymentFilterProps, SmsPaymentSearchCl, SmsCl } from '../../model/sms-payment/types';
import { useStore } from '@/shared/model/store';
import { FilterMotionDuration, FilterMotionStyle, FilterMotionVariants } from '@/entities/common/model/constant';
export const SmsPaymentFilter = ({
@@ -28,11 +28,11 @@ export const SmsPaymentFilter = ({
}: SmsPaymentFilterProps) => {
const [filterMid, setFilterMid] = useState<string>(mid);
const [filterSearchCl, setFilterSearchCl] = useState<SmsPaymentSearchType>(searchCl);
const [filterSearchCl, setFilterSearchCl] = useState<SmsPaymentSearchCl>(searchCl);
const [filterSearchValue, setFilterSearchValue] = useState<string>(searchValue);
const [filterFromDate, setFilterFromDate] = useState<string>(moment(fromDate).format('YYYY.MM.DD'));
const [filterToDate, setFilterToDate] = useState<string>(moment(toDate).format('YYYY.MM.DD'));
const [filterSmsCl, setFilterSmsCl] = useState<SmsType>(smsCl);
const [filterSmsCl, setFilterSmsCl] = useState<SmsCl>(smsCl);
const midOptions = useStore.getState().UserStore.selectOptionsMids;
@@ -52,14 +52,14 @@ export const SmsPaymentFilter = ({
];
let searchTypeOption = [
{ name: '주문자', value: SmsPaymentSearchType.BUYER_NAME },
{ name: '수신번호', value: SmsPaymentSearchType.RECEIVE_PHONE_NUMBER },
{ name: '주문자', value: SmsPaymentSearchCl.BUYER_NAME },
{ name: '수신번호', value: SmsPaymentSearchCl.RECEIVE_PHONE_NUMBER },
]
let smsTypeOption = [
{ name: '전체', value: SmsType.ALL },
{ name: '가상계좌\n요청', value: SmsType.VACCOUNT_REQ },
{ name: '가상계좌\n요청+입금', value: SmsType.VACCOUNT_REQ_DEPOSIT },
{ name: '전체', value: SmsCl.ALL },
{ name: '가상계좌\n요청', value: SmsCl.VACCOUNT_REQ },
{ name: '가상계좌\n요청+입금', value: SmsCl.VACCOUNT_REQ_DEPOSIT },
]
const onClickToClose = () => {

View File

@@ -1,35 +1,64 @@
import { SmsPaymentListProps } from '../../model/sms-payment/types';
import { SmsPaymentListItem, SmsPaymentListProps } from '../../model/sms-payment/types';
import { AdditionalServiceCategory } from '../../model/types';
import { ListDateGroup } from '../list-date-group';
export const SmsPaymentList = ({
listItems,
additionalServiceCategory,
mid,
onResendClick
onResendClick,
setTarget
}: SmsPaymentListProps) => {
const getListDateGroup = () => {
let rs = [];
for (const [key, value] of Object.entries(listItems)) {
let date = '';
let list: SmsPaymentListItem[] = [];
for (let i = 0; i < listItems.length; i++) {
let paymentDate = listItems[i]?.paymentDate || '';
let itemDate = paymentDate.substring(0, 8);
if (i === 0) {
date = itemDate;
}
if (date !== itemDate) {
date = itemDate;
if (list.length > 0) {
rs.push(
<ListDateGroup
additionalServiceCategory={additionalServiceCategory}
onResendClick={onResendClick}
mid={mid}
key={date + '-' + i}
date={date}
items={list as any}
></ListDateGroup>
);
}
list = [];
}
list.push(listItems[i] as any);
}
if (list.length > 0) {
rs.push(
<ListDateGroup
additionalServiceCategory={AdditionalServiceCategory.SMSPayment}
key={key}
date={key}
items={value}
mid={mid}
additionalServiceCategory={additionalServiceCategory}
onResendClick={onResendClick}
mid={mid}
key={date + '-last'}
date={date}
items={list as any}
></ListDateGroup>
)
);
}
return rs;
};
return (
<>
<div className="transaction-list">
<section className="transaction-list">
{getListDateGroup()}
</div>
<div ref={setTarget}></div>
</section>
</>
)
}