Переглянути джерело

郵便番号から住所検索対応

develop
sosuke.iwabuchi 2 роки тому
джерело
коміт
e1fb5dce68
2 змінених файлів з 93 додано та 3 видалено
  1. +67
    -0
      src/api/zipcode.ts
  2. +26
    -3
      src/pages/app/hooks/useInputMailStep.tsx

+ 67
- 0
src/api/zipcode.ts Переглянути файл

@@ -0,0 +1,67 @@
export type GetAddressFromZipCodeResponse = {
success: boolean;
zipcode: string;
prefcode?: string;
address1?: string;
address2?: string;
};

type APIResponse = {
status: number;
message: string | null;
results:
| {
zipcode: string; // 郵便番号 7桁の郵便番号。ハイフンなし。
prefcode: string; // 都道府県コード JIS X 0401 に定められた2桁の都道府県コード。
address1: string; // 都道府県名
address2: string; // 市区町村名
address3: string; // 町域名
kana1: string; // 都道府県名カナ
kana2: string; // 市区町村名カナ
kana3: string; //
}[]
| null;
};

// 郵便番号から住所を検索するAPIを呼ぶ
export async function getAddressFromZipCode(
zipcode: string
): Promise<GetAddressFromZipCodeResponse> {
const url = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode=' + zipcode;

try {
const data = await callAPI(url);

if (data.status !== 200) {
throw Error('ステータス不正:' + data.status);
}
if (data.results === null || data.results.length === 0) {
throw Error('結果0件:' + data.status);
}

const target = data.results[0];

// 正常返却
return {
success: true,
zipcode,
prefcode: target.prefcode,
address1: target.address2,
address2: target.address3,
};
} catch (e) {
if (e instanceof Error) {
console.error('zipcode error', e.message);
}
// エラー返却
return {
success: false,
zipcode,
};
}
}

async function callAPI(url: string): Promise<APIResponse> {
const data = await (await fetch(url)).json();
return data;
}

+ 26
- 3
src/pages/app/hooks/useInputMailStep.tsx Переглянути файл

@@ -1,9 +1,11 @@
import { yupResolver } from "@hookform/resolvers/yup";
import { Box, Button, Divider, Stack, Typography } from "@mui/material";
import { HasChildren } from "@types";
import { getAddressFromZipCode } from "api/zipcode";
import { FormProvider, RHFTextField } from "components/hook-form";
import RHFDatePicker from "components/hook-form/RHFDatePicker";
import RHFPrefCodeSelect from "components/hook-form/ex/RHFPrefCodeSelect";
import useBackDrop from "hooks/useBackDrop";
import useNavigateCustom from "hooks/useNavigateCustom";
import { useForm } from "react-hook-form";
import * as Yup from "yup";
@@ -34,6 +36,8 @@ type Props = {
onPrev?: VoidFunction;
};
export default function useInputMailStep({ onNext, onPrev }: Props) {
const { setShowBackDrop } = useBackDrop();

const form = useForm<FormProps>({
defaultValues: {
mail_pref_code: "",
@@ -65,6 +69,24 @@ export default function useInputMailStep({ onNext, onPrev }: Props) {
),
});

const zipCode = form.watch("mail_zip_code");
const handleBlurZipCode = () => {
if (/^[0-9]{7}$/.test(zipCode)) {
setShowBackDrop(true);
getAddressFromZipCode(zipCode)
.then((res) => {
if (res.success) {
form.setValue("mail_pref_code", res.prefcode ?? "");
form.setValue("mail_address1", res.address1 ?? "");
form.setValue("mail_address2", res.address2 ?? "");
}
})
.finally(() => {
setShowBackDrop(false);
});
}
};

const handleSubmit = () => {
if (onNext) {
onNext();
@@ -80,16 +102,17 @@ export default function useInputMailStep({ onNext, onPrev }: Props) {
const element = (
<FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}>
<Stack spacing={2} sx={{ p: 1, m: 1 }} textAlign="left">
<AreaBox title="都道府県">
<RHFPrefCodeSelect name="mail_pref_code" size="small" />
</AreaBox>
<AreaBox title="郵便番号">
<Typography variant="body2">ハイフン無の7桁</Typography>
<RHFTextField
name="mail_zip_code"
InputProps={{ startAdornment: <div>〒</div> }}
onBlur={handleBlurZipCode}
/>
</AreaBox>
<AreaBox title="都道府県">
<RHFPrefCodeSelect name="mail_pref_code" size="small" />
</AreaBox>
<AreaBox title="市区町村">
<RHFTextField name="mail_address1" />
</AreaBox>


Завантаження…
Відмінити
Зберегти