cm: 우편번호 떼어내기
This commit is contained in:
@@ -2,5 +2,5 @@ import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
return twMerge(clsx(inputs)); //clsx 결과 (단순 합치기):twMerge 결과 (Tailwind 충돌 제거)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export * from "./search_form_right";
|
||||
export * from "./search_input";
|
||||
export * from "./search_input_select";
|
||||
// export * from "./search_input_address";
|
||||
export * from "./search_address";
|
||||
export * from "./select";
|
||||
export * from "./tab";
|
||||
export * from "./table";
|
||||
@@ -24,4 +25,4 @@ export * from "./sdmInsertForm";
|
||||
export * from "./popover_ui";
|
||||
export * from "./date_month_picker";
|
||||
export * from "./date_picker_range"
|
||||
export * from "./map/GisOverlay";
|
||||
export * from "./map/GisOverlay";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Input, Label } from "@common/components";
|
||||
import { Button, Input } from "@common/components";
|
||||
import { AsYouType } from "libphonenumber-js";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
|
||||
@@ -6,10 +6,7 @@ import { FormField } from "../form";
|
||||
import { FormUi } from "../form_ui";
|
||||
import { SelectBox } from "../select";
|
||||
import { SdmSearchForm } from "./sdmNameBox";
|
||||
import { UiModal, UiTable } from '../../ui';
|
||||
import type { Zip, ZipSearchParams } from "../search_input_address/zipService";
|
||||
import { findAddress } from "../search_input_address/findAddress";
|
||||
import { cn } from "@common/components";
|
||||
import { SearchAddressModal } from "../search_address/SearchAddressModal";
|
||||
|
||||
// 수요처 정보
|
||||
export type DemandCompType = {
|
||||
@@ -91,7 +88,6 @@ export function SdmRegForm({
|
||||
readOnly,
|
||||
openNetwork,
|
||||
}: SdmRegFormProps) {
|
||||
const PAGE_SIZE = 10;
|
||||
const [sidoValue, setSidoValue] = useState<string>("");
|
||||
const [sigunValue, setSigunValue] = useState<string>("");
|
||||
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([
|
||||
@@ -104,30 +100,6 @@ export function SdmRegForm({
|
||||
const [zipId, setZipId] = useState<number | undefined>(undefined);
|
||||
const [address, setAddress] = useState<string | undefined>("");
|
||||
const [detailedAddress, setDetailedAddress] = useState<string>("");
|
||||
const [curPage, setCurPage] = useState<number>(1);
|
||||
// 우편번호 검색 관련 상태
|
||||
const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]);
|
||||
const [zipTotalElements, setZipTotalElements] = useState<number>(-1);
|
||||
const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({
|
||||
roadNm: "",
|
||||
bldgNoMno: null,
|
||||
bldgNoSno: null,
|
||||
page: curPage,
|
||||
size: PAGE_SIZE
|
||||
});
|
||||
const [isResetPage, setIsResetPage] = useState<boolean>(false);
|
||||
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
|
||||
const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined);
|
||||
const [selectedZip, setSelectedZip] = useState<Zip>();
|
||||
const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false);
|
||||
|
||||
const handleCellClick = (index: any, headId: any) => {
|
||||
console.log('index', index);
|
||||
console.log('headId', headId);
|
||||
setSelectedZip(zipSearchResults[index]);
|
||||
setIsSelectedZip(true);
|
||||
console.log('selectedZip', zipSearchResults[index]);
|
||||
};
|
||||
|
||||
const formatPhoneNumber = (value: string) => {
|
||||
const input = value;
|
||||
@@ -293,17 +265,6 @@ export function SdmRegForm({
|
||||
[orgBznmNo, setIsDuplicate],
|
||||
);
|
||||
|
||||
// 우편번호 선택 함수
|
||||
const handleSelectAddress = () => {
|
||||
setZipId(selectedZip?.zipId);
|
||||
setAddress(selectedZip?.zipAddr || "");
|
||||
setDetailedAddress("");
|
||||
setIsZipModalOpen(false);
|
||||
setSelectedZip(undefined);
|
||||
setIsSelectedZip(false);
|
||||
setSelectedRowIndex(undefined);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (updateList?.dmdInfoId) {
|
||||
form.reset(updateList);
|
||||
@@ -325,16 +286,6 @@ export function SdmRegForm({
|
||||
console.log("form.formState.errors ", form.formState.errors);
|
||||
}, [form.formState.errors]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("curPage ", curPage);
|
||||
searchQuery.page = curPage - 1;
|
||||
const fetchAddress = async () => {
|
||||
const result = await findAddress(searchQuery);
|
||||
setZipSearchResults(result?.content);
|
||||
};
|
||||
fetchAddress();
|
||||
}, [curPage]);
|
||||
|
||||
// 폼 제출 전에 주소 합치기
|
||||
useEffect(() => {
|
||||
// address와 detailedAddress를 합쳐서 daddr에 설정
|
||||
@@ -344,105 +295,6 @@ export function SdmRegForm({
|
||||
}
|
||||
}, [address, detailedAddress, form]);
|
||||
|
||||
const renderBody = () => (
|
||||
<>
|
||||
<form
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const result = await findAddress(searchQuery);
|
||||
setZipSearchResults(result?.content);
|
||||
setZipTotalElements(result?.totalElements);
|
||||
}}
|
||||
className="mb-4 space-y-2"
|
||||
>
|
||||
{/* 검색 조건 부분 */}
|
||||
<div className="card card-border !m-0 flex flex-col gap-4 p-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 font-bold text-base">도로명</Label>
|
||||
<Input
|
||||
value={searchQuery.roadNm || ""}
|
||||
onChange={(e) =>
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
roadNm: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="예: 테헤란로"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 text-base">건물본번</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={searchQuery.bldgNoMno ?? ""}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
? parseInt(e.target.value)
|
||||
: null;
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
bldgNoMno: value,
|
||||
});
|
||||
}}
|
||||
placeholder="예: 123"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 text-base">건물부번</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={searchQuery.bldgNoSno ?? ""}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
? parseInt(e.target.value)
|
||||
: null;
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
bldgNoSno: value,
|
||||
});
|
||||
}}
|
||||
placeholder="예: 45"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button className="rounded-md" type="submit">검색</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* 검색 결과 부분 */}
|
||||
{zipTotalElements > 0 && (
|
||||
<UiTable
|
||||
headName=''
|
||||
tableData={zipSearchResults}
|
||||
headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]}
|
||||
pageSize={PAGE_SIZE}
|
||||
total={zipTotalElements}
|
||||
cellClick={handleCellClick}
|
||||
onPageChange={setCurPage}
|
||||
resetPageNo={isResetPage}
|
||||
resetSelection={isResetSelection}
|
||||
index={selectedRowIndex}
|
||||
/>
|
||||
)}
|
||||
{zipTotalElements === 0 && (
|
||||
<div className={cn("flex h-96 flex-col items-center justify-center gap-4")}>
|
||||
<i className="diveicon di-info-circle text-3xl" />
|
||||
조회된 데이터가 없습니다.
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
const formFields: Array<{
|
||||
name: keyof FormSchema;
|
||||
@@ -725,35 +577,14 @@ export function SdmRegForm({
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<UiModal
|
||||
headerTitle="주소 검색"
|
||||
headerTitleClass="text-2xl font-bold text-gray-900"
|
||||
<SearchAddressModal
|
||||
open={isZipModalOpen}
|
||||
onOpenChange={setIsZipModalOpen}
|
||||
bodyClass={`
|
||||
${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'}
|
||||
w-[30vw]
|
||||
min-w-[500px]
|
||||
max-w-[90vw]
|
||||
max-h-[85vh]
|
||||
overflow-y-auto
|
||||
!fixed
|
||||
!top-[50%]
|
||||
!left-[50%]
|
||||
!-translate-x-1/2
|
||||
!-translate-y-1/2
|
||||
z-[101]
|
||||
flex
|
||||
flex-col
|
||||
`}
|
||||
body={renderBody()}
|
||||
footerContent={
|
||||
<div className="w-full flex justify-center items-center gap-4">
|
||||
<Button className="rounded-md" size="lg" onClick={handleSelectAddress} disabled={!isSelectedZip}>선택</Button>
|
||||
<Button className="rounded-md" size="lg" onClick={() => setIsZipModalOpen(false)}>취소</Button>
|
||||
</div>
|
||||
}
|
||||
useDirectRender={true}
|
||||
onSelect={(zip) => {
|
||||
setZipId(zip.zipId);
|
||||
setAddress(zip.zipAddr || "");
|
||||
setDetailedAddress("");
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
import { Button, Input, Label, cn } from "@common/components";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { UiModal } from "../dialog_ui";
|
||||
import { UiTable } from "../table";
|
||||
import type { Zip, ZipSearchParams } from "./zipService";
|
||||
import { findAddress } from "./findAddress";
|
||||
|
||||
interface SearchAddressModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onSelect: (zip: Zip) => void;
|
||||
}
|
||||
|
||||
export function SearchAddressModal({ open, onOpenChange, onSelect }: SearchAddressModalProps) {
|
||||
const PAGE_SIZE = 10;
|
||||
const [curPage, setCurPage] = useState<number>(1);
|
||||
const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]);
|
||||
const [zipTotalElements, setZipTotalElements] = useState<number>(-1);
|
||||
const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({
|
||||
roadNm: "",
|
||||
bldgNoMno: null,
|
||||
bldgNoSno: null,
|
||||
page: 1,
|
||||
size: PAGE_SIZE
|
||||
});
|
||||
const [isResetPage, setIsResetPage] = useState<boolean>(false);
|
||||
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
|
||||
const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined);
|
||||
const [selectedZip, setSelectedZip] = useState<Zip>();
|
||||
const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false);
|
||||
|
||||
// Initialize/Reset state when modal opens
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setCurPage(1);
|
||||
setZipSearchResults([]);
|
||||
setZipTotalElements(-1);
|
||||
setSearchQuery({
|
||||
roadNm: "",
|
||||
bldgNoMno: null,
|
||||
bldgNoSno: null,
|
||||
page: 0,
|
||||
size: PAGE_SIZE
|
||||
});
|
||||
setSelectedZip(undefined);
|
||||
setIsSelectedZip(false);
|
||||
setSelectedRowIndex(undefined);
|
||||
setIsResetPage(true);
|
||||
setTimeout(() => setIsResetPage(false), 100);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
// Pagination Effect
|
||||
useEffect(() => {
|
||||
if (!open || zipTotalElements === -1) return;
|
||||
|
||||
// Correctly update query for pagination without mutation
|
||||
const nextPage = curPage - 1;
|
||||
if (searchQuery.page !== nextPage) {
|
||||
const newQuery = { ...searchQuery, page: nextPage };
|
||||
setSearchQuery(newQuery);
|
||||
|
||||
const fetchAddress = async () => {
|
||||
const result = await findAddress(newQuery);
|
||||
setZipSearchResults(result?.content || []);
|
||||
};
|
||||
fetchAddress();
|
||||
}
|
||||
}, [curPage, open, zipTotalElements]);
|
||||
|
||||
const handleCellClick = (index: any) => {
|
||||
setSelectedZip(zipSearchResults[index]);
|
||||
setIsSelectedZip(true);
|
||||
setSelectedRowIndex(index);
|
||||
};
|
||||
|
||||
const handleSearch = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const query = { ...searchQuery, page: 0 };
|
||||
setSearchQuery(query);
|
||||
setCurPage(1);
|
||||
setIsResetPage(true);
|
||||
|
||||
const result = await findAddress(query);
|
||||
setZipSearchResults(result?.content || []);
|
||||
setZipTotalElements(result?.totalElements || 0);
|
||||
|
||||
setTimeout(() => setIsResetPage(false), 100);
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (selectedZip) {
|
||||
onSelect(selectedZip);
|
||||
onOpenChange(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<UiModal
|
||||
headerTitle="주소 검색"
|
||||
headerTitleClass="text-2xl font-bold text-gray-900"
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
bodyClass={`
|
||||
${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'}
|
||||
w-[30vw]
|
||||
min-w-[500px]
|
||||
max-w-[90vw]
|
||||
min-h-[235px]
|
||||
overflow-y-auto
|
||||
!fixed
|
||||
!top-[50%]
|
||||
!left-[50%]
|
||||
!-translate-x-1/2
|
||||
!-translate-y-1/2
|
||||
z-[101]
|
||||
flex
|
||||
flex-col
|
||||
`}
|
||||
body={
|
||||
<>
|
||||
<form
|
||||
onSubmit={handleSearch}
|
||||
className="mb-4 space-y-2"
|
||||
>
|
||||
<div className="card card-border !m-0 flex flex-col gap-4 p-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 font-bold text-base">도로명</Label>
|
||||
<Input
|
||||
value={searchQuery.roadNm || ""}
|
||||
onChange={(e) =>
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
roadNm: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="예: 테헤란로"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 text-base">건물본번</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={searchQuery.bldgNoMno ?? ""}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
? parseInt(e.target.value)
|
||||
: null;
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
bldgNoMno: value,
|
||||
});
|
||||
}}
|
||||
placeholder="예: 123"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<Label className="mb-1 text-base">건물부번</Label>
|
||||
<Input
|
||||
type="number"
|
||||
value={searchQuery.bldgNoSno ?? ""}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
? parseInt(e.target.value)
|
||||
: null;
|
||||
setSearchQuery({
|
||||
...searchQuery,
|
||||
bldgNoSno: value,
|
||||
});
|
||||
}}
|
||||
placeholder="예: 45"
|
||||
className="!text-[1.3rem]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button className="rounded-md" type="submit">검색</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{zipTotalElements > 0 && (
|
||||
<UiTable
|
||||
headName=''
|
||||
tableData={zipSearchResults}
|
||||
headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]}
|
||||
pageSize={PAGE_SIZE}
|
||||
total={zipTotalElements}
|
||||
cellClick={handleCellClick}
|
||||
onPageChange={setCurPage}
|
||||
resetPageNo={isResetPage}
|
||||
resetSelection={isResetSelection}
|
||||
index={selectedRowIndex}
|
||||
/>
|
||||
)}
|
||||
{zipTotalElements === 0 && (
|
||||
<div className={cn("flex h-96 flex-col items-center justify-center gap-4")}>
|
||||
<i className="diveicon di-info-circle text-3xl" />
|
||||
조회된 데이터가 없습니다.
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
footerContent={
|
||||
<div className="w-full flex justify-center items-center gap-4">
|
||||
<Button className="rounded-md" size="lg" onClick={handleConfirm} disabled={!isSelectedZip}>선택</Button>
|
||||
<Button className="rounded-md" size="lg" onClick={() => onOpenChange(false)}>취소</Button>
|
||||
</div>
|
||||
}
|
||||
useDirectRender={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
|
||||
// const Key = 'U01TX0FVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA'
|
||||
// const addresssKey = 'devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM='; //인증키 만료일은 2025-11-23
|
||||
|
||||
import type { Zip, ZipSearchParams } from "./zipService";
|
||||
|
||||
/**
|
||||
* 주소 API 응답 타입
|
||||
* https://business.juso.go.kr/addrlink/main.do 해당 사이트 참조
|
||||
*/
|
||||
export type AddressApiResponse = {
|
||||
results: {
|
||||
common: {
|
||||
errorMessage: string;
|
||||
countPerPage: string;
|
||||
totalCount: string;
|
||||
errorCode: string;
|
||||
currentPage: string;
|
||||
};
|
||||
juso: addressType[];
|
||||
};
|
||||
}
|
||||
|
||||
export type addressType = {
|
||||
detBdNmList: string;
|
||||
engAddr: string;
|
||||
rn: string;
|
||||
emdNm: string;
|
||||
zipNo: string;
|
||||
roadAddrPart2: string;
|
||||
emdNo: string;
|
||||
sggNm: string;
|
||||
jibunAddr: string;
|
||||
siNm: string;
|
||||
roadAddrPart1: string;
|
||||
bdNm: string;
|
||||
admCd: string;
|
||||
udrtYn: string;
|
||||
lnbrMnnm: string;
|
||||
roadAddr: string;
|
||||
lnbrSlno: string;
|
||||
buldMnnm: string;
|
||||
bdKdcd: string;
|
||||
liNm: string;
|
||||
rnMgtSn: string;
|
||||
mtYn: string;
|
||||
bdMgtSn: string;
|
||||
buldSlno: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주소에 따른 검색
|
||||
* @param search : 검색어
|
||||
* @returns addressType[] 주소 배열
|
||||
*/
|
||||
export const findAddress = async (searchQuery: ZipSearchParams): Promise<any> => {
|
||||
if (!searchQuery) return [];
|
||||
|
||||
// 쿼리 파라미터 생성
|
||||
const params = new URLSearchParams();
|
||||
if (searchQuery.roadNm) params.append('roadNm', searchQuery.roadNm);
|
||||
if (searchQuery.bldgNoMno != null) params.append('bldgNoMno', searchQuery.bldgNoMno.toString());
|
||||
if (searchQuery.bldgNoSno != null) params.append('bldgNoSno', searchQuery.bldgNoSno.toString());
|
||||
if (searchQuery.page != null) params.append('page', searchQuery.page.toString());
|
||||
if (searchQuery.size != null) params.append('size', searchQuery.size.toString());
|
||||
|
||||
const url = `/cms-service/api/v1/zips?${params.toString()}`;
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error('Network response was not ok');
|
||||
|
||||
const data = await response.json();
|
||||
if (data) return data
|
||||
else return [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching address data:', error);
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const searchFilter = (search: string) => {
|
||||
|
||||
|
||||
if (search.length > 0) {
|
||||
//특수문자 제거
|
||||
const expText = /[%=><]/;
|
||||
if (expText.test(search) == true) {
|
||||
alert("특수문자를 입력 할수 없습니다.");
|
||||
search = search.split(expText).join("");
|
||||
return false;
|
||||
}
|
||||
|
||||
//특정문자열(sql예약어의 앞뒤공백포함) 제거
|
||||
const sqlArray = [
|
||||
//sql 예약어
|
||||
"OR", "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE", "DROP", "EXEC",
|
||||
"UNION", "FETCH", "DECLARE", "TRUNCATE"
|
||||
]
|
||||
|
||||
let regex;
|
||||
for (let i = 0; i < sqlArray.length; i++) {
|
||||
regex = new RegExp(sqlArray[i] as string, "gi");
|
||||
|
||||
if (regex.test(search)) {
|
||||
alert("\"" + sqlArray[i] + "\"와(과) 같은 특정문자로 검색할 수 없습니다.");
|
||||
search = search.replace(regex, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./SearchAddressModal";
|
||||
export * from "./findAddress";
|
||||
export * from "./zipService";
|
||||
@@ -0,0 +1,66 @@
|
||||
interface SortConfig {
|
||||
empty: boolean;
|
||||
sorted: boolean;
|
||||
unsorted: boolean;
|
||||
}
|
||||
|
||||
interface PageableConfig {
|
||||
sort: SortConfig;
|
||||
offset: number;
|
||||
pageNumber: number;
|
||||
pageSize: number;
|
||||
paged: boolean;
|
||||
unpaged: boolean;
|
||||
}
|
||||
|
||||
export interface PageableList<T> {
|
||||
content: T[];
|
||||
pageable: PageableConfig;
|
||||
sort: SortConfig;
|
||||
totalPages: number;
|
||||
totalElements: number;
|
||||
number: number;
|
||||
numberOfElements: number;
|
||||
size: number;
|
||||
first: boolean;
|
||||
last: boolean;
|
||||
empty: boolean;
|
||||
}
|
||||
|
||||
export interface PageableParams {
|
||||
page?: number;
|
||||
size?: number;
|
||||
sort?: string;
|
||||
}
|
||||
|
||||
|
||||
export interface ZipSearchParams extends PageableParams {
|
||||
zoneNo?: string; // 구역번호
|
||||
ctpvNm?: string; // 시도명
|
||||
sggNm?: string; // 시군구명
|
||||
emdNm?: string; // 읍면동명
|
||||
roadNm?: string; // 도로명
|
||||
stdgNm?: string; // 법정동명
|
||||
dongNm?: string; // 행정동명
|
||||
bldgNoMno?: number | null; // 빌딩본번
|
||||
bldgNoSno?: number | null; // 빌딩딩부번
|
||||
lotnoMno?: number | null; // 지번본번
|
||||
lotnoSno?: number | null; // 지번부번
|
||||
}
|
||||
|
||||
export interface Zip {
|
||||
zipId: number;
|
||||
zoneNo: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
emdNm: string;
|
||||
roadNm: string;
|
||||
bldgNoMno: number;
|
||||
bldgNoSno: number;
|
||||
lotnoMno: number;
|
||||
lotnoSno: number;
|
||||
lotno: string;
|
||||
zipAddr: string;
|
||||
}
|
||||
|
||||
export type ZipList = PageableList<Zip>;
|
||||
Reference in New Issue
Block a user