import { fetchType, getFetch, postFetch } from "@/components/ui/api"; import type { SelectDataType } from "@common/business_components/ui"; import type { TableUpperProps } from "../common"; import toast from "react-hot-toast"; import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; import { z } from "zod"; /**==================================== * Store - 타입 =====================================*/ export const sdmInfoFormSchema = z.object({ sdmNm: z.string().min(1, "수요처를 선택해주세요"), demandYmd: z.date().optional(), demandQnty: z .string() .min(1, "요구수량을 입력해주세요") .regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"), usePurpose: z.string().optional(), money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"), /**요구수질 */ reqWaterQlty: z.string().optional(), grssClfg: z.number().nullish(), tn: z.number().nullish(), combResdch: z.number().nullish(), tph: z.number().nullish(), trbt: z.number().nullish(), ph: z.string().nullish(), bod: z.number().nullish(), /**컬럼확인필요 */ clIonQnt: z.number().nullish(), smll: z.string(), cdtnv: z.number().nullish(), crmty: z.number().nullish(), rmrk: z.string().optional(), /* telno: z.string() .min(8, "전화번호는 8자 이상 입력해주세요") .max(12, "전화번호는 12자 이내로 입력해주세요") .regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), */ candidateTitle: z .array( z.object({ ruseUtztnFcltNm: z.string(), ruseUtztnFcltCd: z.string(), }) ) .optional(), }).superRefine((data, ctx) => { const disabledFields = disableRules[data.usePurpose ?? ""] || []; // 모든 수질 관련 필드 // 총대장균군수는 null 값을 불검출로 표시하기때문에 해당 검사에서 제외함. const allFields: (keyof typeof data)[] = [ "tn", "combResdch", "tph", "trbt", "ph", "bod", "clIonQnt", "smll", "cdtnv", "crmty", ]; const allFieldsName: Record = { tn: "총질소(T-N)(mg/L)", combResdch: "결합잔류염소(mg/L)", tph: "총인(T-P)(mg/L)", trbt: "탁도(NTU)", ph: "수소이온농도(pH)", bod: "생물학적 산소요구량(BOD)(mg/L)", clIonQnt: "염화물(mgCL/L)", smll: "냄새", cdtnv: "전기전도도(㎲/cm)", crmty: "색도(도)", }; allFields.forEach((field) => { const isDisabled = disabledFields.includes(field); if (!isDisabled) { // disabled가 아닌 필드는 반드시 값이 있어야 함 const value = data[field]; if (typeof value === "string") { if (value.trim().length === 0) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: [field], message: `${allFieldsName[field]} 을 입력해주세요.`, }); } } else if (typeof value === "number") { if (value <= 0 || Number.isNaN(value)) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: [field], message: `${allFieldsName[field]} 을 입력해주세요.`, }); } } else if (value == null) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: [field], message: `${allFieldsName[field]} 을 입력해주세요.`, }); } } }); }); export type SdmInfoFormData = z.infer; // 수요처 정보 export type DemandCompBizType = { index: number | ''; dmdInfoId: string | ''; dmdInfoFk: string | ''; bzmnNo: string | ''; dmdCoNm: string | ''; zip: string | ''; daddr: string | ''; telno: string | ''; rgtr: string | ''; useUsgCd: string | ''; ctpvCd: string | ''; sggCd: string | ''; dmdAplyPswd: string | ''; wntUntprc: number | ''; dmndTmng: Date | ''; dmndQty: number | ''; grssClfg: number | null //총대장균군수 tn: number | null //총질소 combResdch: number | null //결합잔류염소 tph: number | null //총인 trbt: number | null //탁도 ph: string | ''; //수소이온농 blgcOxygDmndQnt: number | null //생물학적산소요구량 clIonQnt: number | null //염화물 smll: string | ''; //냄새 cdtnv: number | null; //전기전도도 crmty: number | null //색도 rmrk: string | ''; reqDt: string | ''; dmdInfoSn: number | ''; status: string | ''; splyCndtList: SupplyCandidate[] | [], ruseUtztnFcltNm?: string | '' } // 공급 후보자 타입 정의 export type SupplyCandidate = { ruseUtztnFcltNm: string; ruseUtztnFcltCd: string; }; export type DemandMatchings = { splyFcltFk: string | ''; splyFcltFlg: string | ''; pbnstRuseFcltBizFk: number | ''; splyBgngDay: string | ''; splyEndDay: string | ''; splyCpct: number | ''; splyFmYn: string | ''; useUsgCd: string | ''; dmdInfoSn: number | ''; splyCndtList: string | ''; mtchnCmptnYmd: string | ''; rvwCmptnYmd: string | ''; regDt: string | ''; rgtr: string | ''; mdfcnDt: string | ''; mdfr: string | ''; } // 유사사례 export type SimilarCaseType = { ruseBizNm: string | ''; // 사업명 bizBgngDate: string | ''; bizEndDate: string | ''; splyFcltKnd: string | ''; splyFcltNm: string | ''; splyFcltCpct: string | ''; dmdFcltNm: string | ''; dmdFcltAddr: string | ''; ruseFcltCpct: string | ''; ruseFcltPplLen: string | ''; ruseFcltUsg: string | ''; ruseFcltSplyCpct: string | ''; ruseFcltPrcsMsrc: string | ''; grnteWqUsg: string | ''; grnteWqGrssClfg: string | ''; grnteWqCombResdch: string | ''; grnteWqTrbt: string | ''; grnteWqBod: string | ''; grnteWqSmll: string | ''; grnteWqCrmty: string | ''; grnteWqTn: string | ''; grnteWqTp: string | ''; grnteWqPh: string | ''; grnteWqClIonQnt: string | ''; grnteWqCndctStat: string | ''; grnteWqRmrk: string | ''; reqBizReuseFcltCst: string | ''; reqBizPplCst: string | ''; reqBizArchCst: string | ''; reqBizMchnCst: string | ''; reqBizMtrngCst: string | ''; reqBizGisCst: string | ''; reqBizCctvCst: string | ''; reqBizCmcnCst: string | ''; reqBizWstCst: string | ''; reqBizDesignCst: string | ''; reqBizSpvsCst: string | ''; reqBizSbsdCst: string | ''; reqBizEtc: string | ''; reqBizGrssCst: string | ''; prcmPlanNlep: string | ''; prcmPlanLcep: string | ''; prcmPlanBrdnCst: string | ''; prcmPlanEcqrRt: string | ''; prcmPlanGrssCst: string | ''; clclnNlep: string | ''; clclnLcep: string | ''; clclnBrdnCst: string | ''; clclnEcqrRt: string | ''; clclnGrssCst: string | ''; } // 사업비 상세정보 export type MoneyDetailType = { reqBizGrssCst: string | ''; reqBizReuseFcltCst: string | ''; reqBizPplCst: string | ''; reqBizArchCst: string | ''; reqBizMchnCst: string | ''; reqBizMtrngCst: string | ''; reqBizGisCst: string | ''; reqBizCctvCst: string | ''; reqBizCmcnCst: string | ''; reqBizWstCst: string | ''; reqBizDesignCst: string | ''; reqBizSpvsCst: string | ''; reqBizSbsdCst: string | ''; reqBizEtc: string | ''; /** 재원조달계획(백만원원) */ prcmPlanGrssCst: string | ''; prcmPlanNlep: string | ''; prcmPlanLcep: string | ''; prcmPlanBrdnCst: string | ''; prcmPlanEcqrRt: string | ''; /** 사업비 정산(백만원) */ clclnGrssCst: string | ''; clclnNlep: string | ''; clclnLcep: string | ''; clclnBrdnCst: string | ''; clclnEcqrRt: string | ''; } // 규칙 타입 선언 export type DisableRulesType = Record; /**==================================== * Store - 데이터 ====================================*/ // 수요처 정보 const demandCompList: DemandCompType[] = [ ] const disableRules: DisableRulesType = { "청소": ["tn", 'tph', "clIonQnt", 'cdtnv'], "화장실용수": ["tn", 'tph', "clIonQnt", 'cdtnv'], "세척": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'], "살수": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'], "조경": ["combResdch", "crmty", 'tph', 'cdtnv'], "농업_간접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'], "농업_직접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'], "하천": ["combResdch", "trbt", "crmty", 'clIonQnt', 'cdtnv'], '공업': [] }; const defaultRules: Record = { "청소": { grssClfg: null, combResdch: 0.2, trbt: 2, bod: 5, crmty: 20, ph: "5.8~8.5", smll: '불쾌하지않을것', tn: null, tph: null, clIonQnt: null, cdtnv: null, }, "화장실용수": { grssClfg: null, combResdch: 0.2, trbt: 2, bod: 5, crmty: 20, smll: '불쾌하지않을것', ph: "5.8~8.5", tn: null, tph: null, clIonQnt: null, cdtnv: null, }, "세척": { grssClfg: null, trbt: 2, bod: 5, ph: "5.8~8.5", combResdch: null, smll: '불쾌하지않을것', crmty: null, tn: null, tph: null, clIonQnt: null, cdtnv: null, }, "살수": { grssClfg: null, trbt: 2, bod: 5, ph: "5.8~8.5", smll: '불쾌하지않을것', combResdch: null, crmty: null, tn: null, tph: null, clIonQnt: null, cdtnv: null, }, "조경": { grssClfg: null, trbt: 2, bod: 5, ph: "5.8~8.5", smll: '불쾌하지않을것', clIonQnt: 250, combResdch: null, crmty: null, tn: null, tph: null, cdtnv: null, }, "농업_간접용수": { grssClfg: null, trbt: 5, bod: 8, ph: "5.8~8.5", cdtnv: 2000, combResdch: null, crmty: null, tn: null, tph: null, clIonQnt: null, }, "농업_직접용수": { grssClfg: null, trbt: 2, bod: 8, smll: '불쾌하지않을것', ph: "5.8~8.5", cdtnv: 700, combResdch: null, crmty: null, tn: null, tph: null, clIonQnt: null, }, "하천": { grssClfg: 1000, bod: 5, tn: 10, tph: 0.5, smll: '불쾌하지않을것', ph: "5.8~8.5", combResdch: null, trbt: null, crmty: null, clIonQnt: null, cdtnv: null }, '공업': { grssClfg: null, bod: null, tn: null, tph: null, ph: "~", combResdch: null, smll: '불쾌하지않을것', trbt: null, crmty: null, clIonQnt: null, cdtnv: null } }; // 사용용도 const useTypesData: SelectDataType[] = [ { text: '청소', val: "청소" }, { text: "화장실용수", val: "화장실용수" }, { text: "세척", val: "세척" }, { text: "살수", val: "살수" }, { text: "조경", val: "조경" }, { text: "농업_간접용수", val: "농업_간접용수" }, { text: "농업_직접용수", val: "농업_직접용수" }, { text: "하천", val: "하천" }, { text: "공업", val: "공업" }, ]; // 유사사례 모달 헤더 export const similarCaseModalHeader: TableUpperProps[] = [ { id: "ruseBizNm", title: "사업명", row: 0, rowSpan: 2 }, { id: "bizBgngDate", title: "사업시작일", row: 0, rowSpan: 2 }, { id: "bizEndDate", title: "사업종료일", row: 0, rowSpan: 2 }, { id: "A", title: "공급처", row: 0, colSpan: 3 }, { id: "splyFcltKnd", title: "시설종류", row: 1 }, { id: "splyFcltNm", title: "공급처명", row: 1 }, { id: "splyFcltCpct", title: "시설용량\n(㎥/일)", row: 1 }, { id: "B", title: "수요처", row: 0, colSpan: 2 }, { id: "dmdFcltNm", title: "수요처명", row: 1 }, { id: "dmdFcltAddr", title: "주소", row: 1 }, { id: "C", title: "재이용시설", row: 0, colSpan: 5 }, { id: "ruseFcltCpct", title: "시설용량\n(㎥/일)", row: 1 }, { id: "ruseFcltPplLen", title: "관로\n(km)", row: 1 }, { id: "ruseFcltUsg", title: "용도", row: 1 }, { id: "ruseFcltSplyCpct", title: "공급량\n(㎥/일)", row: 1 }, { id: "ruseFcltPrcsMsrc", title: "처리공법", row: 1 }, { id: "D", title: "보증수질", row: 0, colSpan: 13 }, { id: "grnteWqUsg", title: "용도별", row: 1 }, { id: "grnteWqGrssClfg", title: "총대장균군수\n(개/100ml)", row: 1 }, { id: "grnteWqCombResdch", title: "결합잔류염소\n(mg/L)", row: 1 }, { id: "grnteWqTrbt", title: "탁도\n(NTU)", row: 1 }, { id: "grnteWqBod", title: "생물학적산소요구량\n(BOD)\n(mg/L)", row: 1 }, { id: "grnteWqSmll", title: "냄새\n(개/100ml)", row: 1 }, { id: "grnteWqCrmty", title: "색도\n(도)", row: 1 }, { id: "grnteWqTn", title: "총질소\n(T-N)\n(mg/L)", row: 1 }, { id: "grnteWqTp", title: "총인\n(T-P)\n(mg/L)", row: 1 }, { id: "grnteWqPh", title: "수소이온농도\n(pH)", row: 1 }, { id: "grnteWqClIonQnt", title: "염화물\n(mgCL/L)", row: 1 }, { id: "grnteWqCndctStat", title: "전기전도도\n(μS/cm)", row: 1 }, { id: "grnteWqRmrk", title: "비고", row: 1 }, { id: "reqBizGrssCst", title: "소요사업비\n(백만원)", row: 0, rowSpan: 2 }, ] // 유사사례 데이터 const similarCaseList: SimilarCaseType[] = [ ] // 사업비 상세정보 모달 헤더 export const moneyDetailModalHeader: TableUpperProps[] = [ { id: "A", title: "소요사업비(백만원)", row: 0, colSpan: 14 }, { id: "reqBizGrssCst", title: "총", row: 1, rowSpan: 2 }, { id: "B", title: "토목", row: 1, colSpan: 2 }, { id: "reqBizReuseFcltCst", title: "재이용시설", row: 2 }, { id: "reqBizPplCst", title: "관로", row: 2 }, { id: "reqBizArchCst", title: "건축", row: 1, rowSpan: 2 }, { id: "reqBizMchnCst", title: "기계", row: 1, rowSpan: 2 }, { id: "reqBizMtrngCst", title: "전기,계측", row: 1, rowSpan: 2 }, { id: "reqBizGisCst", title: "GIS/DB", row: 1, rowSpan: 2 }, { id: "reqBizCctvCst", title: "CCTV", row: 1, rowSpan: 2 }, { id: "reqBizCmcnCst", title: "시공 및 준공", row: 1, rowSpan: 2 }, { id: "reqBizWstCst", title: "폐기물", row: 1, rowSpan: 2 }, { id: "reqBizDesignCst", title: "설계비", row: 1, rowSpan: 2 }, { id: "reqBizSpvsCst", title: "감리비", row: 1, rowSpan: 2 }, { id: "reqBizSbsdCst", title: "시설 부대비", row: 1, rowSpan: 2 }, { id: "reqBizEtc", title: "기타", row: 1, rowSpan: 2 }, { id: "C", title: "재원조달계획(백만원)", row: 0, colSpan: 5 }, { id: "prcmPlanGrssCst", title: "총", row: 1, rowSpan: 2 }, { id: "prcmPlanNlep", title: "국비", row: 1, rowSpan: 2 }, { id: "prcmPlanLcep", title: "지방비", row: 1, rowSpan: 2 }, { id: "prcmPlanBrdnCst", title: "원인자부담", row: 1, rowSpan: 2 }, { id: "prcmPlanEcqrRt", title: "국고비율", row: 1, rowSpan: 2 }, { id: "D", title: "사업비 정산(백만원)", row: 0, colSpan: 5 }, { id: "clclnGrssCst", title: "총", row: 1, rowSpan: 2 }, { id: "clclnNlep", title: "국비", row: 1, rowSpan: 2 }, { id: "clclnLcep", title: "지방비", row: 1, rowSpan: 2 }, { id: "clclnBrdnCst", title: "원인자부담", row: 1, rowSpan: 2 }, { id: "clclnEcqrRt", title: "국고비율", row: 1, rowSpan: 2 }, ] // 사업비 상세정보 const moneyDetailList: MoneyDetailType[] = [ ] // 수요정보 신청현황 헤더 export const upHeadSdmInfoStatus: TableUpperProps[] = [ { id: "index", title: "No." }, { id: "ctpvCd", title: "시도", row: 0, rowSpan: 2 }, { id: "sggCd", title: "시군구", row: 0, rowSpan: 2 }, { id: "dmdCoNm", title: "회사명", row: 0, rowSpan: 2 }, { id: "daddr", title: "공장주소", row: 0, rowSpan: 2 }, { id: "telno", title: "전화번호", row: 0, rowSpan: 2 }, { id: "dmndTmng", title: "신청일자", row: 0, rowSpan: 2 }, { id: "status", title: "진행상태", row: 0, rowSpan: 2 }, ] // 수요정보 신청현황 데이터 /**==================================== * Store - Api =====================================*/ // 수요처 등록 const postSdmData = async (data: DemandCompType) => { try { await postFetch("/reuseFc/request", data); sessionStorage.setItem("user", JSON.stringify(data)); toast.success("수요처 등록에 성공하였습니다."); return true; } catch (error) { console.log(error); toast.error("수요처 등록에 실패하였습니다."); return false; } } // 수요정보 등록 const postSdmInfoData = async (data: DemandCompBizType) => { try { await postFetch("/reuseFc/request/demandInfo", data); toast.success('수요 정보 등록에 성공하였습니다.'); } catch (error) { console.log(error); toast.error('수요 정보 등록에 실패하였습니다.'); } } const postSdmLoginData = async (data: DemandCompType) => { try { const res = await postFetch("/reuseFc/request/login", data); const jsonData = await res.json(); const status = jsonData.status; const loginData = jsonData.data; let loginSuccess = false; if (status === 200 && loginData != null) { alert("수요처 로그인에 성공하였습니다."); delete loginData.dmdAplyPswd; delete loginData.rgtr; sessionStorage.setItem("user", JSON.stringify(loginData)); loginSuccess = true; } else if (status === 401) { alert("패스워드가 일치하지 않습니다."); loginSuccess = false; } else { alert("등록된 수요처가 없습니다."); loginSuccess = false; } return loginSuccess; } catch (error) { console.log(error); alert("수요처 로그인에 실패하였습니다."); } } const getDemandCompList = async (searchText: string, pageCnt: number) => { try { const url = '/reuseFc/request/' + (searchText ? searchText : '') + '/' + pageCnt; const res = await getFetch(fetchType.WR, url); return { data: res?.data || [], count: res?.count || 0 } } catch (error) { console.error(error + ' 수요처 정보를 불러오지 못했습니다.'); return { data: [], count: 0 }; } } const getSdmInfoStatusList = async (dmdInfoId: string) => { try { const url = '/reuseFc/request/' + dmdInfoId; const res = await getFetch(fetchType.WR, url); return res?.data || []; } catch (error) { console.error(error + ' 수요정보 신청현황을 불러오지 못했습니다.'); return []; } } // 유사사례 조회 const fetchGetSimilarCaseList = async (part: string, value: number | string) => { try { const url = '/reuseFc/pubFcRuseCase/dm/' + part + '/' + (value ? value : 0); const res = await getFetch(fetchType.WR, url); return res?.data || []; } catch (error) { console.error(error + ' 유사사례 조회에 실패하였습니다.'); return []; } } /**==================================== * Store - expaort ====================================*/ export type SdmActions = { initializeSdmData: () => void; insertSdmData: (data: DemandCompType) => Promise; insertSdmInfoData: (data: DemandCompBizType) => Promise; getDemandCompList: (searchText: string, pageCnt: number) => Promise; actionLogin: (data: DemandCompType) => Promise; getSdmInfoStatusList: (dmdInfoId: string) => Promise; getSimilarCaseList: (part: string, value: number | string) => Promise; actionLogout: () => Promise; } export type SdmType = { Sdm: { isInit: boolean; useTypesData: SelectDataType[]; demandCompList: DemandCompType[]; upHeadSimilarCaseList: TableUpperProps[]; similarCaseList: SimilarCaseType[]; upHeadMoneyDetailList: TableUpperProps[]; moneyDetailList: MoneyDetailType[]; // 수요정보 신청현황 sdmInfoStatusList: DemandCompBizType[]; upHeadSdmInfoStatus: TableUpperProps[]; defaultRules: Record disableRules: DisableRulesType; // 로그인관련 successNextPage: boolean; successLogin: boolean; } } export const SdmState: SdmType = { Sdm: { isInit: false, useTypesData: useTypesData, demandCompList: demandCompList, upHeadSimilarCaseList: similarCaseModalHeader, similarCaseList: similarCaseList, upHeadMoneyDetailList: moneyDetailModalHeader, moneyDetailList: moneyDetailList, // 수요정보 신청현황 sdmInfoStatusList: [], defaultRules: defaultRules, disableRules: disableRules, upHeadSdmInfoStatus: upHeadSdmInfoStatus, // 로그인관련 successNextPage: false, successLogin: false, } } export const SdmReducer = (set: any): SdmActions => { return { initializeSdmData: async () => { }, insertSdmData: async (data: DemandCompType) => { const preRes = await getSdmInfoStatusList(data.dmdInfoId); if (preRes?.dmdInfoId) { toast.error('이미 등록된 수요처입니다.'); return; } const res = await postSdmData(data); if (res) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, successNextPage: true, } })) } }, insertSdmInfoData: async (data: DemandCompBizType) => { postSdmInfoData(data); }, // 수요처 정보 getDemandCompList: async (searchText: string, pageCnt: number) => { const res = await getDemandCompList(searchText, pageCnt); if (res.data.length === 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, demandCompList: [], } })) return; } else { set((state: SdmType) => ({ Sdm: { ...state.Sdm, demandCompList: res.data, } })) } }, // 수요정보 신청현황 getSdmInfoStatusList: async (dmdInfoId: string) => { const res = await getSdmInfoStatusList(dmdInfoId); if (res.length === 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, sdmInfoStatusList: [], } })) return; } //const sdmInfoStatusList : DemandCompBizType[] = []; const sdmInfoStatusList: DemandCompBizType[] = res.demandInfo.map((el: DemandCompBizType, index: number) => { const matchingInfo = res.demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn); const status = matchingInfo?.splyFcltFlg?.trim() === 'Sub' ? '검토' : matchingInfo?.splyFcltFlg?.trim() === 'matched' ? '매칭완료' : '신청'; const ruseUtztnFcltNm = matchingInfo?.ruseUtztnFcltNm ? matchingInfo.ruseUtztnFcltNm : ''; return ({ ...el, index: ++index, bzmnNo: res.bzmnNo, dmdCoNm: res.dmdCoNm, dmdInfoId: res.dmdInfoId, zip: res.zip || '', daddr: res.daddr, telno: res.telno.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3'), rgtr: res.rgtr, ctpvCd: res.ctpvCd, sggCd: res.sggCd, useUsgCd: el.useUsgCd, dmndTmng: el.dmndTmng, dmdInfoSn: el.dmdInfoSn, status: status, splyCndtList: el.splyCndtList, ruseUtztnFcltNm: ruseUtztnFcltNm || '' }) }) set((state: SdmType) => ({ Sdm: { ...state.Sdm, sdmInfoStatusList: sdmInfoStatusList, } })) }, actionLogin: async (data: DemandCompType) => { const loginSuccess = await postSdmLoginData(data); set((state: SdmType) => ({ Sdm: { ...state.Sdm, successLogin: loginSuccess, } })) }, // 유사사례 조회 getSimilarCaseList: async (part: string, value: number | string) => { const res = await fetchGetSimilarCaseList(part, value); const similarCaseList = res.map((el: SimilarCaseType) => { const maskedBizNm = el.ruseBizNm ? el.ruseBizNm.replace(/^(\s*)^\S+/, "***") // 첫 단어(공백 전까지) 치환 : el.ruseBizNm; return { ...el, ruseBizNm: maskedBizNm, }; }); console.log(similarCaseList); if (similarCaseList && similarCaseList.length !== 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, similarCaseList: similarCaseList, } })) return; } else { set((state: SdmType) => ({ Sdm: { ...state.Sdm, similarCaseList: [], } })) return; } }, actionLogout: async () => { sessionStorage.removeItem("user"); set((state: SdmType) => ({ Sdm: { ...state.Sdm, successLogin: false, } })) } } } export type SdmStore = SdmType & SdmActions;