계좌성명조회

This commit is contained in:
focp212@naver.com
2025-11-04 09:57:54 +09:00
parent 25c282b41d
commit 424c1c3ddb
8 changed files with 226 additions and 90 deletions

View File

@@ -24,6 +24,7 @@ export interface AccountHolderSearchListItem {
export interface AccountHolderSearchListProps { export interface AccountHolderSearchListProps {
listItems: Array<AccountHolderSearchListItem>; listItems: Array<AccountHolderSearchListItem>;
mid: string; mid: string;
setDetailData: (detailData: DetailData) => void;
} }
export interface AccountHolderSearchFilterProps extends FilterProps { export interface AccountHolderSearchFilterProps extends FilterProps {
@@ -46,7 +47,7 @@ export interface AccountHolderSearchFilterProps extends FilterProps {
// 계좌 성명 조회 확장 서비스 // 계좌 성명 조회 확장 서비스
import { DefaulResponsePagination, DefaultRequestPagination } from "@/entities/common/model/types"; import { DefaulResponsePagination, DefaultRequestPagination } from "@/entities/common/model/types";
import { ExtensionRequestParams, FilterProps, ListItemProps, ProcessResult } from "../types"; import { DetailData, ExtensionRequestParams, FilterProps, ListItemProps, ProcessResult } from "../types";
// ======================================== // ========================================
export interface ExtensionAccountHolderSearchListParams extends ExtensionRequestParams { // Request export interface ExtensionAccountHolderSearchListParams extends ExtensionRequestParams { // Request

View File

@@ -148,8 +148,8 @@ export interface DetailInfoSectionProps extends DetailResponse {
export interface DetailData { export interface DetailData {
tid: string; mid?: string;
serviceCode?: string; tid?: string;
detailOn: boolean; detailOn: boolean;
} }

View File

@@ -2,79 +2,81 @@ import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ListDateGroup } from '../list-date-group'; import { ListDateGroup } from '../list-date-group';
import { AdditionalServiceCategory } from '../../model/types' import { AdditionalServiceCategory } from '../../model/types'
import { AccountHolderSearchListItem, AccountHolderSearchListProps } from '../../model/account-holder-search/types'; import { AccountHolderSearchListProps } from '../../model/account-holder-search/types';
import { JSX } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export const AccountHolderSearchList = ({ export const AccountHolderSearchList = ({
listItems, listItems,
mid mid,
setDetailData
}: AccountHolderSearchListProps) => { }: AccountHolderSearchListProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const { t } = useTranslation(); const { t } = useTranslation();
const getListDateGroup = () => { const getListDateGroup = () => {
let rs = []; let rs = [];
let date = ''; let date = '';
let list = []; let list = [];
for (let i = 0; i < listItems.length; i++) { for(let i = 0; i < listItems.length; i++){
let items = listItems[i]; let items = listItems[i];
if (!!items) { if (!!items) {
let requestDate = items?.requestDate; let requestDate = items?.requestDate;
requestDate = requestDate?.substring(0, 8); requestDate = requestDate?.substring(0, 8);
if (!!requestDate) { if (!!requestDate) {
if (i === 0) { if (i === 0) {
date = requestDate; date = requestDate;
} }
if (date !== requestDate) { if(date !== requestDate){
if (list.length > 0) { if (list.length > 0) {
rs.push( rs.push(
<ListDateGroup <ListDateGroup
additionalServiceCategory={AdditionalServiceCategory.AccountHolderSearch} additionalServiceCategory={AdditionalServiceCategory.AccountHolderSearch}
key={date + '-' + i} key={date + '-' + i}
mid={mid} mid={mid}
date={date} date={date}
items={list} items={list}
></ListDateGroup> setDetailData={ setDetailData }
); ></ListDateGroup>
} );
date = requestDate; }
list = []; date = requestDate;
} list = [];
list.push(items); }
} list.push(items);
} }
} }
if (list.length > 0) { }
rs.push( if(list.length > 0){
<ListDateGroup rs.push(
additionalServiceCategory={AdditionalServiceCategory.AccountHolderSearch} <ListDateGroup
mid={mid} additionalServiceCategory={AdditionalServiceCategory.AccountHolderSearch}
key={date + '-last'} mid={mid}
date={date} key={date + '-last'}
items={list} date={date}
></ListDateGroup> items={list}
); setDetailData={ setDetailData }
} ></ListDateGroup>
return rs; );
}; }
return rs;
};
const onClickToNavigate = () => { const onClickToNavigate = () => {
navigate(PATHS.additionalService.accountHolderSearch.request) navigate(PATHS.additionalService.accountHolderSearch.request)
}; };
return ( return (
<> <>
<section className="transaction-list"> <section className="transaction-list">
{getListDateGroup()} {getListDateGroup()}
</section> </section>
<div className="apply-row"> <div className="apply-row">
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={() => onClickToNavigate()} onClick={() => onClickToNavigate()}
>{t('additionalService.accountHolderSearch.searchRequest')}</button> >{t('additionalService.accountHolderSearch.searchRequest')}</button>
</div> </div>
</> </>
); );
} }

View File

@@ -0,0 +1,120 @@
import moment from 'moment';
import { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ExtensionAccountHolderSearchDetailParams, ExtensionAccountHolderSearchDetailResponse } from '@/entities/additional-service/model/account-holder-search/types';
import { useExtensionAccountHolderSearchDetailtMutation } from '@/entities/additional-service/api/account-holder-search/use-extension-account-holder-search-detail-mutation';
import { getAccountHolderStatusText } from '@/entities/additional-service/model/account-holder-search/constant';
import { useTranslation } from 'react-i18next';
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
export interface AccountHolderSearchDetailProps {
detailOn: boolean;
setDetailOn: (detailOn: boolean) => void;
mid: string;
tid: string;
};
export const AccountHolderSearchDetail = ({
detailOn,
setDetailOn,
mid,
tid
}: AccountHolderSearchDetailProps) => {
const { t } = useTranslation();
const [detail, setDetail] = useState<ExtensionAccountHolderSearchDetailResponse>();
const { mutateAsync: accountHolderSearchDetail } = useExtensionAccountHolderSearchDetailtMutation();
const callDetail = () => {
let accountHolderSearchDetailParams: ExtensionAccountHolderSearchDetailParams = {
mid: mid,
tid: tid
};
accountHolderSearchDetail(accountHolderSearchDetailParams).then((rs: ExtensionAccountHolderSearchDetailResponse) => {
setDetail(rs);
});
};
const getDate = (date?: string) => {
return (date) ? moment(date, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '';
};
const onClickToClose = () => {
setDetailOn(false);
};
useEffect(() => {
if(!!mid && !!tid){
callDetail();
}
}, [mid, tid]);
return (
<>
<motion.div
className="full-menu-modal"
initial="hidden"
animate={ (detailOn)? 'visible': 'hidden' }
variants={ DetailMotionVariants }
transition={ DetailMotionDuration }
style={ DetailMotionStyle }
>
<div className="full-menu-container pdw-16">
<div className="full-menu-header">
<div className="full-menu-title center">{ t('transaction.detailTitle') }</div>
<div className="full-menu-actions">
<FullMenuClose
addClass="full-menu-close"
onClickToCallback={ onClickToClose }
></FullMenuClose>
</div>
</div>
<div className="tab-pane sub active">
<div className="pay-top">
<div className="num-amount">
<span className="amount">{detail?.accountNo}</span>
</div>
<span className="num-day">{detail?.bankName}</span>
<div className="num-day">{getDate(detail?.requestDate)}</div>
</div>
<div className="detail-divider"></div>
<div className="pay-detail">
<div className="detail-title">{t('transaction.sections.detailInfo')}</div>
<ul className="kv-list">
<li className="kv-row">
<span className="k">{t('transaction.fields.accountHolder')}</span>
<span className="v">{detail?.accountName}</span>
</li>
<li className="kv-row">
<span className="k">{t('additionalService.accountHolderAuth.requestDate')}</span>
<span className="v">{getDate(detail?.requestDate)}</span>
</li>
<li className="kv-row">
<span className="k">{t('common.result')}</span>
<span className="v">{getAccountHolderStatusText(t)(detail?.resultStatus)}</span>
</li>
<li className="kv-row">
<span className="k">{t('transaction.fields.failureReason')}</span>
<span className="v">{detail?.failReason ? detail?.failReason : '-' }</span>
</li>
<li className="kv-row">
<span className="k">{t('transaction.fields.bank')}</span>
<span className="v">{detail?.bankName}</span>
</li>
<li className="kv-row">
<span className="k">{t('transaction.fields.accountNo')}</span>
<span className="v">{detail?.accountNo}</span>
</li>
<li className="kv-row">
<span className="k">{t('additionalService.accountHolderAuth.requestWay')}</span>
<span className="v">{detail?.requestWay}</span>
</li>
</ul>
</div>
</div>
</div>
</motion.div>
</>
);
}

View File

@@ -10,7 +10,8 @@ export const ListDateGroup = ({
mid, mid,
date, date,
items, items,
onResendClick onResendClick,
setDetailData
}: ListDateGroupProps) => { }: ListDateGroupProps) => {
const { i18n } = useTranslation(); const { i18n } = useTranslation();
@@ -93,6 +94,7 @@ export const ListDateGroup = ({
onResendClick={ onResendClick } onResendClick={ onResendClick }
seq= { items[i]?.seq} seq= { items[i]?.seq}
setDetailData={ setDetailData }
></ListItem> ></ListItem>
) )
} }

View File

@@ -34,7 +34,8 @@ export const ListItem = ({
smsCl, groupId, userMallId, transType, smsCl, groupId, userMallId, transType,
authResult, failReason, requestTime, authResult, failReason, requestTime,
resendEnabled, resendEnabled,
onResendClick onResendClick,
setDetailData
}: ListItemProps) => { }: ListItemProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
@@ -169,13 +170,14 @@ export const ListItem = ({
}) })
} }
else if (additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch) { else if (additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch) {
navigate(PATHS.additionalService.accountHolderSearch.detail, { if(setDetailData && !!mid && !!tid){
state: { setDetailData({
additionalServiceCategory: additionalServiceCategory,
mid: mid, mid: mid,
tid: tid tid: tid,
} detailOn: true
}); });
}
} }
else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentHistory) { else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentHistory) {
navigate(PATHS.additionalService.linkPayment.detail, { navigate(PATHS.additionalService.linkPayment.detail, {

View File

@@ -85,7 +85,7 @@ export const ListItem = ({
const onClickToNavigate = () => { const onClickToNavigate = () => {
if(transactionCategory === TransactionCategory.AllTransaction){ if(transactionCategory === TransactionCategory.AllTransaction){
if(setDetailData && tid){ if(setDetailData && !!tid){
setDetailData({ setDetailData({
tid: tid, tid: tid,
serviceCode: serviceCode, serviceCode: serviceCode,
@@ -94,7 +94,7 @@ export const ListItem = ({
} }
} }
else if(transactionCategory === TransactionCategory.CashReceipt){ else if(transactionCategory === TransactionCategory.CashReceipt){
if(setDetailData && tid){ if(setDetailData && !!tid){
setDetailData({ setDetailData({
tid: tid, tid: tid,
detailOn: true detailOn: true
@@ -102,7 +102,7 @@ export const ListItem = ({
} }
} }
else if(transactionCategory === TransactionCategory.Escrow){ else if(transactionCategory === TransactionCategory.Escrow){
if(setDetailData && tid){ if(setDetailData && !!tid){
setDetailData({ setDetailData({
tid: tid, tid: tid,
serviceCode: serviceCode, serviceCode: serviceCode,
@@ -111,7 +111,7 @@ export const ListItem = ({
} }
} }
else if(transactionCategory === TransactionCategory.Billing){ else if(transactionCategory === TransactionCategory.Billing){
if(setDetailData && tid){ if(setDetailData && !!tid){
setDetailData({ setDetailData({
tid: tid, tid: tid,
detailOn: true detailOn: true

View File

@@ -26,6 +26,7 @@ import { useTranslation } from 'react-i18next';
import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access-check'; import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access-check';
import useIntersectionObserver from '@/widgets/intersection-observer'; import useIntersectionObserver from '@/widgets/intersection-observer';
import { snackBar } from '@/shared/lib'; import { snackBar } from '@/shared/lib';
import { AccountHolderSearchDetail } from '@/entities/additional-service/ui/account-holder-search/detail/account-holder-search-detail';
export const AccountHolderSearchPage = () => { export const AccountHolderSearchPage = () => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
@@ -52,8 +53,8 @@ export const AccountHolderSearchPage = () => {
const [resultStatus, setResultStatus] = useState<AccountHolderResultStatus>(AccountHolderResultStatus.ALL); const [resultStatus, setResultStatus] = useState<AccountHolderResultStatus>(AccountHolderResultStatus.ALL);
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false); const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
const [detailOn, setDetailOn] = useState<boolean>(false); const [detailOn, setDetailOn] = useState<boolean>(false);
const [detailMid, setDetailMid] = useState<string>('');
const [detailTid, setDetailTid] = useState<string>(''); const [detailTid, setDetailTid] = useState<string>('');
const [detailServiceCode, setDetailServiceCode] = useState<string>('');
useSetHeaderTitle(t('additionalService.services.accountHolderSearch')); useSetHeaderTitle(t('additionalService.services.accountHolderSearch'));
useSetHeaderType(HeaderType.LeftArrow); useSetHeaderType(HeaderType.LeftArrow);
@@ -173,11 +174,13 @@ export const AccountHolderSearchPage = () => {
setResultStatus(val); setResultStatus(val);
}; };
const setDetailDate = (detailData: DetailData) => { const setDetailData = (detailData: DetailData) => {
setDetailOn(detailData.detailOn); setDetailOn(detailData.detailOn);
setDetailTid(detailData.tid); if(detailData.mid){
if(detailData?.serviceCode) { setDetailMid(detailData.mid);
setDetailServiceCode(detailData?.serviceCode); }
if(detailData.tid){
setDetailTid(detailData.tid);
} }
} }
@@ -259,8 +262,9 @@ export const AccountHolderSearchPage = () => {
</div> </div>
</div> </div>
<AccountHolderSearchList <AccountHolderSearchList
listItems={listItems} listItems={ listItems }
mid={mid} mid={ mid }
setDetailData={ setDetailData }
></AccountHolderSearchList> ></AccountHolderSearchList>
<div ref={setTarget}></div> <div ref={setTarget}></div>
</div> </div>
@@ -284,7 +288,12 @@ export const AccountHolderSearchPage = () => {
setBank={setBank} setBank={setBank}
setResultStatus={setResultStatus} setResultStatus={setResultStatus}
></AccountHolderSearchFilter> ></AccountHolderSearchFilter>
<AccountHolderSearchDetail
detailOn={ detailOn }
setDetailOn={ setDetailOn }
mid={ detailMid }
tid={ detailTid }
></AccountHolderSearchDetail>
<EmailBottomSheet <EmailBottomSheet
bottomSheetOn={emailBottomSheetOn} bottomSheetOn={emailBottomSheetOn}
setBottomSheetOn={setEmailBottomSheetOn} setBottomSheetOn={setEmailBottomSheetOn}