From 5dfb52457ba8c3ae4685fa3c7afad7fefa105c30 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Thu, 22 May 2025 17:38:02 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=20=EC=A7=80?= =?UTF-8?q?=EB=8F=84=EC=A0=90=EA=B2=80=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B3=B5=EA=B3=B5=20=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=9E=A5=20=EB=93=B1=EB=A1=9D=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 22 +- .../ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 2 +- .../prfmncSttn/chkgdnSttn/page.tsx | 8 - .../prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx | 22 +- .../ruseFcltMng/fcltReg/bdstReg/index.tsx | 9 +- .../ruseFcltMng/fcltReg/pbnstReg/headList.tsx | 49 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 190 ++++---- .../ruseFcltMng/fcltReg/pbnstReg/type.tsx | 442 ++++++++++++++++++ apps/wr/components/lib/config/index.ts | 2 + apps/wr/components/lib/useTus_wr/useTusWr.tsx | 53 +++ .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 3 +- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 135 +----- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 107 +++-- .../ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx | 6 +- apps/wr/middleware.ts | 50 ++ apps/wr/package.json | 3 +- apps/wr/public/sample_rs_chk.xlsx | Bin 12474 -> 12581 bytes 17 files changed, 807 insertions(+), 296 deletions(-) create mode 100644 apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx create mode 100644 apps/wr/components/lib/useTus_wr/useTusWr.tsx create mode 100644 apps/wr/middleware.ts diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index a3c4e4110..8994e46c1 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -10,20 +10,20 @@ import { } from "@common/business_components"; import { Button, Input } from "@common/components"; import { useWrStore } from "../../../store"; -import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; -import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { useEffect, useState } from "react"; -import type { customPbnst, ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg"; import ListDiv from "@common/business_components/ui/list_div"; import { tableData } from "@/components/lib/func/commom"; +import type { customPbnst, ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; +import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; export default function PublicReuseFaciltyInsert() { - const { code, pubFac, pubHasuInit } = useWrStore((state) => state); - const { pubFacHeadList } = pubFac; + const { code, pbnst, pubHasuInit } = useWrStore((state) => state); + const { pubFacHeadList,pbnstHasuRes } = pbnst; - const {pbnstReg} = pubFac + const {pbnstRes} = pbnst const [currentTab, setCurrentTab] = useState("mng"); const [fcltMng, setFcltMng] = useState(); const [searchTxt, setSearchTxt] = useState(); @@ -31,17 +31,17 @@ export default function PublicReuseFaciltyInsert() { useEffect(() => { - if (!pubFac.isInit) { + if (!pbnst.isInit) { pubHasuInit(undefined); } - }, [pubFac.isInit, pubHasuInit]); + }, [pbnst.isInit, pubHasuInit]); useEffect(() => { if (code.sggCd.length > 0) { - setbdstTable(tableData(pbnstReg, { code })); + setbdstTable(tableData(pbnstHasuRes, { code })); } - }, [code, pbnstReg]); + }, [code, pbnstHasuRes]); const onSelectValue = (val: string) => { @@ -109,7 +109,7 @@ useEffect(() => { total={10} headName={"공공 하수처리시설 등록"} cellClick={cellClick} - onPageChange={(page: number) => { } } children={undefined} /> + onPageChange={(page: number) => { } } children={undefined} /> diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index 955a4f7d6..c6ffe6807 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -88,7 +88,7 @@ export default function Page() { if (rswtChkgdn.excelList[0]?.data.length > 1) excelArrayDownload( - "중수도_점검결과_이용량현황", + "중수도시설 지도점검", "sample_rs_chk.xlsx", rswtChkgdn.excelList ); diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx index f0bf16393..eca2033c4 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx @@ -70,8 +70,6 @@ export default function Page() { },[rswtChkSttn.isInit, rswtChkSttnInit]) - - const handleClick = useCallback( (data: any) => { if (data) setIsModal({ open: !isModal.open, data: data }); @@ -79,9 +77,6 @@ export default function Page() { [isModal] ); const excelDown=() =>{ - - - console.log("excelDown" , rainChkSttn.sttnExcelList) if(rainChkSttn.sttnExcelList && selFcltDiv === "RNB"){ excelDownload( rainChkSttn.sttnExcelList, @@ -90,10 +85,7 @@ const excelDown=() =>{ "A1:Q2", 3 ); - - }else if(rswtChkSttn.sttnExcelList && selFcltDiv === "RST"){ - console.log("rswtChkSttn " , rswtChkSttn.sttnExcelList) excelDownload( rswtChkSttn.sttnExcelList, "중수도시설 지도점검 현황", diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx index f8593fa51..1364d6660 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx @@ -28,6 +28,7 @@ export const rswtMakeExcelSample = ( "", "", "", + "", useType, "", "", @@ -72,6 +73,7 @@ export const rswtMakeExcelSample = ( "", "", "", + "", useType, "", "", @@ -145,15 +147,15 @@ export const excelToRswtGuideData = (excelData: any, year: string) => { return { bdstRuseFcltFk: Number(item["NO"]), + operMngCd: item["운영관리형태"], + anlOperCst: Number(item["연간운영비(원/년)"]) ?? 0, + prcsCpct: item["처리용량(m³)"], + spwtPositn: item["채수지점"], chckYmd:checkYmd, utztnUsgCd: item["이용용도"], - spwtPositn: item["유량측정방법"], + guideDetails: makeGuidDetail, rgtr: TEST_UUID, mdfr: TEST_UUID, - oilqMeasMthd: item["운영관리형태"], - anlOperCst: Number(item["연간운영비(원/년)"]) ?? 0, - operMngCd: item["유량측정방법"], - guideDetails: makeGuidDetail, }; } @@ -210,13 +212,13 @@ export const excelToRswtPolution = (excelData: any, year: string) => { bdstRuseFcltFk: Number(item["NO"]), chckYmd: checkYmd, utztnUsgCd: item["이용용도"], - spwtPositn: item["유량측정방법"], + operMngCd: item["운영관리형태"], + anlOperCst: Number(item["연간운영비(원/년)"]) ?? 0, + prcsCpct: item["처리용량(m³)"], + spwtPositn: item["채수지점"], + rswtrPollutions: makePoluttion, rgtr: TEST_UUID, mdfr: TEST_UUID, - oilqMeasMthd: item["운영관리형태"], - anlOperCst: Number(item["연간운영비(원/년)"]) ?? 0, - operMngCd: item["유량측정방법"], - rswtrPolutions: makePoluttion, rswtrDetails: [ { utztnUsgCd: item["이용용도"], diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx index 4b35220da..f72bf7692 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx @@ -1,6 +1,5 @@ import { getFetch } from "@/components/lib/api"; import { TEST_UUID, type customRainBdst } from "../rainReg"; -import type { TableProps } from "../pbnstReg"; import type { customHtdflBdst } from "../htdflReg"; import type { customRswtBdst } from "../rswtReg"; @@ -23,7 +22,7 @@ type TableUpperProps = { ]; - const bdstChgHeadList: TableProps[] = [ + const bdstChgHeadList: TableUpperProps[] = [ { id: "bdstChgNm", title: "구분" }, { id: "archChgPrmsnDt", title: "허가일" }, { id: "archChgArea", title: "변경면적" }, @@ -144,10 +143,6 @@ const isRswtBdst = (data: any): data is customRswtBdst =>{ } - - - - export type bdstFulType = bdstState & bdstActions; @@ -155,7 +150,7 @@ export type bdstState = { bdst: { bdstBase: any[]; moUpHeadList:TableUpperProps[] - bdstChgHeadList:TableProps[] + bdstChgHeadList:TableUpperProps[] }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index ef4101e9a..f24d33ad3 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -2,6 +2,9 @@ import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/head import type { TableUpperProps } from "../rainReg"; + + + export const pubFacHeadListExport: TableUpperProps[] = [ { id: "sido", title: "시도" }, { id: "gugun", title: "시군구" }, @@ -33,41 +36,41 @@ export type formDetailType ={ export const wasteWaterFcltINfo:formDetailType[]=[ - {id:'username' , lable:'폐수배출물신고 허가여부'}, - {id:'username' , lable:'Tms설치여부'}, - {id:'username' , lable:'공공하수도유입제외 허가여부'}, + {id:'wwtEmsnFcltPrmsnYn' , lable:'폐수배출물신고 허가여부'}, + {id:'tmsInstlYn' , lable:'Tms설치여부'}, + {id:'pbnstDrngInflwExclYn' , lable:'공공하수도유입제외 허가여부'}, ] export const concentratedWaterInfo:formDetailType[]=[ -{id:'username' , lable:'눙축수 발생량(m³/일)'}, -{id:'username' , lable:'눙축수연계지점'}, -{id:'username' , lable:'시설용량(m³/일)'}, -{id:'username' , lable:'눙축수처리방식'}, -{id:'username' , lable:'눙축수처리공법'}, +{id:'erctWtrOcrnCpct' , lable:'눙축수 발생량(m³/일)'}, +{id:'erctUswtrLinkSpt' , lable:'눙축수연계지점'}, +{id:'erctUswtrFcltCpct' , lable:'시설용량(m³/일)'}, +{id:'erctUswtrPrcsMeth' , lable:'눙축수처리방식'}, +{id:'erctUswtrPrcsMsrcCd' , lable:'눙축수처리공법'}, ] export const ruseFcltinfo:formDetailType[]=[ - {id:'username' , lable:'시설용량(m³/일)'}, - {id:'username' , lable:'주처리공법'}, - {id:'username' , lable:'위치(주소)'}, - {id:'username' , lable:'재처리방식'}, - {id:'username' , lable:'위치(처리장 내외)'}, - {id:'username' , lable:'메인공급펌프 용량'}, + {id:'rprcsFcltCpct' , lable:'시설용량(m³/일)'}, + {id:'majorPrcsMsrcCd' , lable:'주처리공법'}, + {id:'addr' , lable:'위치(주소)'}, + {id:'rprcsMthdCd' , lable:'재처리방식'}, + {id:'inoutYn' , lable:'위치(처리장 내외)'},// 머가 내? 외?, + {id:'mainSplyPumpCpct' , lable:'메인공급펌프 용량'}, ] export const businessMoneyInfo:formDetailType[]=[ - {id:'username' , lable:'국고'}, - {id:'username' , lable:'지방비'}, + {id:'gvsbs' , lable:'국고'}, + {id:'lcep' , lable:'지방비'}, {id:'username' , lable:'민간투자비'}, - {id:'username' , lable:'원인자부담금'}, - {id:'username' , lable:'기타'}, - {id:'username' , lable:'합계'}, + {id:'cusr_alotm' , lable:'원인자부담금'}, + {id:'etc' , lable:'기타'}, + {id:'totalMoney' , lable:'합계'}, ] export const businessSttnInfo:formDetailType[]=[ - {id:'username' , lable:'구분'}, - {id:'username' , lable:'사업방식'}, - {id:'username' , lable:'사업준공일' ,type:'date'}, - {id:'username' , lable:'설치승인인가일' ,type:'date'} , + {id:'seCd' , lable:'구분'}, + {id:'bizMthdCd' , lable:'사업방식'}, + {id:'bizCmcnDay' , lable:'사업준공일' ,type:'date'}, + {id:'instlAprvSncnDt' , lable:'설치승인인가일' ,type:'date'} , ] \ No newline at end of file diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 6438fecaf..b8e3a00ea 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -3,128 +3,142 @@ import type { TableUpperProps } from "../rainReg"; import { getFetch } from "@/components/lib/api"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; import { pubFacHeadListExport, pubMngNmExport, pubMngUpHeadListExport } from "./headList"; +import { exampleData, fcBizSchema, type customPbnst, type pubHasuType } from "./type"; +import type { SelectDataType } from "@common/business_components/ui"; -export const pbnstZod = z.object({ - bscFctCd:z.string(), - sido:z.string().default(""), - gugun: z.string().default(""), - bscFctNm:z.string().default(""), - efflWqltStndrdNm:z.string().default(""), - fctCpc:z.number().default(0) - -}) - - -export type customPbnst = z.infer - - -export const pbnstReg =[] as customPbnst[]; -export type TableProps = { - id: string; - title: string; -}; - - - - -export type selectLabel = { - text: string; - val: string; -}; - -export type publicReuseFacilityType = { - sido: string; - sigungo: string; - facilityName: string; - location: string; - locationgubun: string; - facilityCapacity: string; - yn?: string; - authoDay?: string; - area?: string; - reuse?: string; - register?: string; - swtrmtFcltFk: string; -}; -export type fcltOperInfoType = { - mng: string; - subCo: string; - startDay: string; - endDay: string; - pbnstRuseFcltPk: string; -}; - -export type ruseFcltType = { - swtrmtFcltFk: string; - pbnstRuseFcltPk:string; - fcltNm:string; - fcltCpct: number; - swtrmtCpct: number; - ruseCpct:number; - splyExtraCpct:number; -}; -const selectLabel: selectLabel[] = [{ text: "test", val: "1" }]; +const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }]; const pubFacHeadList= pubFacHeadListExport; const pubMngUpHeadList = pubMngUpHeadListExport const pubMngNm= pubMngNmExport; export type pubFacState = { - pubFac: { + pbnst: { isInit: boolean; - pubFacHeadList: TableProps[]; + pubFacHeadList: TableUpperProps[]; pubMngUpHeadList: TableUpperProps[]; pubMngNm: chHeadType[]; - selectLabel: selectLabel[]; - pbnstReg:customPbnst[]; - } + pbnstHasuRes: pubHasuType[] + selectLabel: SelectDataType[]; + pbnstRes: customPbnst[]; + pbnstBizCycle: SelectDataType[]; + }; }; type pubFacActions = { - pubHasuInit: (txt:string|undefined) => void; + pbnstRegInit: (sgg: string) => void; + pbnstRegSearch: (txt: string | undefined, sgg: string) => void; + pbnstReg: (txt: string | undefined) => void; + pubHasuInit: (txt: string | undefined) => void; }; export type pubFacType = pubFacState & pubFacActions; export const pubFacStateExport: pubFacState = { - pubFac: { + pbnst: { isInit: false, pubFacHeadList: pubFacHeadList, pubMngUpHeadList: pubMngUpHeadList, selectLabel: selectLabel, - pubMngNm:pubMngNm, - pbnstReg:pbnstReg, + pubMngNm: pubMngNm, + pbnstHasuRes: [], + pbnstRes: [], + pbnstBizCycle:[] }, - }; -const initFetch = async (txt:string|undefined) => { - - const rainRes =await getFetch("common", `/prcsFclt/info/1/10/'A'/41220` +(txt? `/${txt}`:'')+'/0'+'/1' ); - - return rainRes +const initFetch = async (txt: string | undefined) => { + const rainRes = await getFetch( + "common", + `/prcsFclt/info/1/10/A/41220` + (txt ? `/${txt}` : "") + "/500" + "/1" + ); + return rainRes; }; + +const getBizCycle = async (fcBizs: z.infer[] ) => { + const pbnstBizCycle =fcBizs.map((item: z.infer) => { + return { + text: `${item.cycl}차수`, + val: item.cycl, + }; + }); + return pbnstBizCycle; +} export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { return { - pubHasuInit: async(txt:string |undefined)=>{ - try{ - const pbnstReg = await initFetch(txt) - return set((state:pubFacState)=>({ + pubHasuInit: async (txt: string | undefined) => { + try { + const pbnstHasuRes = await initFetch(txt); + + + return set((state: pubFacState) => ({ ...state, - pubFac:{ - ...state.pubFac, - pbnstReg:pbnstReg, + pbnst: { + ...state.pbnst, + pbnstHasuRes:pbnstHasuRes, isInit: false, - } - })) - - }catch(errorHasu){ - console.log(errorHasu) + }, + })); + } catch (errorHasu) { + console.log(errorHasu); } + }, + pbnstRegInit: async (txt: string | undefined) => { + try { + //const pbnstRes = await initFetch(txt); + const pbnstRes = exampleData; - } + const pbnstBizCycle = getBizCycle(pbnstRes?.fcBizs); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + pbnstRes: pbnstRes, + pbnstBizCycle:pbnstBizCycle, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + pbnstRegSearch: async (txt: string | undefined, sgg: string) => { + try { + const pbnstRes = await getFetch( + "wr", + `/api/v1/reuseFc/pubFc` + (txt ? `/${txt}` : "") + `/${sgg}` + ); + const pbnstBizCycle = getBizCycle(pbnstRes.fcBizs); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + pbnstReg: pbnstRes, + pbnstBizCycle:pbnstBizCycle, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + pbnstReg: async (txt: string | undefined) => { + try { + const pbnstRes = await initFetch(txt); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + pbnstRes: pbnstRes, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx new file mode 100644 index 000000000..1a8f1479f --- /dev/null +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -0,0 +1,442 @@ +import { z } from "zod"; + +export type customPbnst = z.infer; + +export const pbnstReg = [] as customPbnst[]; +export type TableProps = { + id: string; + title: string; +}; + +export type selectLabel = { + text: string; + val: string; +}; + +export type publicReuseFacilityType = { + sido: string; + sigungo: string; + facilityName: string; + location: string; + locationgubun: string; + facilityCapacity: string; + yn?: string; + authoDay?: string; + area?: string; + reuse?: string; + register?: string; + swtrmtFcltFk: string; +}; +export type fcltOperInfoType = { + mng: string; + subCo: string; + startDay: string; + endDay: string; + pbnstRuseFcltPk: string; +}; + +export type ruseFcltType = { + swtrmtFcltFk: string; + pbnstRuseFcltPk: string; + fcltNm: string; + fcltCpct: number; + swtrmtCpct: number; + ruseCpct: number; + splyExtraCpct: number; +}; + +const pplInstlSchema = z.object({ + ruseFcltBizFk: z.string(), + pdmt: z.string(), + ppMqlt: z.string(), + cpct: z.string(), +}); +const fcFileSchema = z.object({ + ruseFcltFk: z.number().default(0), + fileTkn: z.string().default("test"), + filePath: z.string().default("test"), + fileKnd: z.string().default("test"), + regDt: z.date().default(new Date()), + rgtr: z.string().default("test"), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string().default("test"), +}); + +const fcOperSchema = z.object({ + pbnstRuseFcltOperInfoPk: z.number().default(0), + pbnstRuseFcltFk: z.number().default(0), + operMthd: z.string(), + rprtvBzenty: z.string(), + bgngDt: z.date().default(new Date()), + endDt: z.date().default(new Date()), + regDt: z.date().default(new Date()), + rgtr: z.string().default("test"), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string().default("test"), +}); + +const fcOrgwtSchema = z.object({ + pbnstRuseFcltBizFk: z.number().default(0), + swtrmtFcltFk: z.number().default(0), + orgwtWtritQnt: z.string(), + tmsYn: z.string(), + dschgFmYn: z.string(), + dtlPstnExpln: z.string(), + regDt: z.date().default(new Date()), + rgtr: z.string().default("test"), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string().default("test"), +}); + +const fcPrfmncSchema = z.object({ + pbnstRuseFcltFk: z.number().default(0), + ym: z.string(), + wshwtr: z.string(), + coolUswtr: z.string(), + cleanUswtr: z.string(), + drwtUswtr: z.string(), + dltnUswtr: z.string(), + ithlRswtr: z.string(), + ithlEtcUswtr: z.string(), + cleanToilUswtr: z.string(), + resn: z.string(), + lndwtr: z.string(), + hydUswtr: z.string(), + rvrKeepUswtr: z.string(), + farmUswtr: z.string(), + ugwtChr: z.string(), + indstUswtr: z.string(), + regDt: z.date().default(new Date()), + rgtr: z.string().default("test"), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string().default("test"), +}); + +export const fcBizSchema = z.object({ + pbnstRuseFcltBizPk: z.number().default(0), + pbnstRuseFcltFk: z.number().default(0), + cycl: z.string(), + seCd: z.string(), + bizMthdCd: z.string(), + instlAprvSncnDt: z.string(), + bizCmcnDay: z.string(), + gvsbs: z.string(), + lcep: z.string(), + cusrAlotm: z.string(), + etc: z.string(), + totalMoney: z.string(), + rprcsFcltCpct: z.string(), + majorPrcsMsrcCd: z.string(), + addr: z.string(), + rprcsMthdCd: z.string(), + inoutYn: z.string(), + mainSplyPumpCpct: z.string(), + erctWtrOcrnCpct: z.string(), + erctUswtrLinkSpt: z.string(), + erctUswtrFcltCpct: z.string(), + erctUswtrPrcsMeth: z.string(), + erctUswtrPrcsMsrcCd: z.string(), + wwtEmsnFcltPrmsnYn: z.string(), + tmsInstlYn: z.string(), + pbnstDrngInflwExclYn: z.string(), + bod: z.string(), + grssClfg: z.string(), + combResdch: z.string(), + trbt: z.string(), + clIonQnt: z.string(), + smll: z.string(), + crmty: z.string(), + tph: z.string(), + tn: z.string(), + ph: z.string(), + cdtnv: z.string(), + designCst: z.string(), + cstrnSpvsCst: z.string(), + fcltSbsdCst: z.string(), + wstCst: z.string(), + cnstCmcnCst: z.string(), + mntrgEqpmntInstlCst: z.string(), + gisDbCst: z.string(), + elpwrMtrngCst: z.string(), + mchnCst: z.string(), + archCst: z.string(), + pplCst: z.string(), + ruseFcltCst: z.string(), + designCstClcln: z.string(), + cstrnSpvsCstClcln: z.string(), + fcltSbsdCstClcln: z.string(), + wstCstClcln: z.string(), + cnstCmcnCstClcln: z.string(), + mntrgEqpmntInstlCstClcln: z.string(), + gisDbCstClcln: z.string(), + elpwrMtrngCstClcln: z.string(), + mchnCstClcln: z.string(), + archCstClcln: z.string(), + pplCstClcln: z.string(), + ruseFcltCstClcln: z.string(), + fcOrgwts: z.array(fcOrgwtSchema), + pplInstls: z.array(pplInstlSchema), + flg: z.string(), + regDt: z.string(), + rgtr: z.string(), + mdfcnDt: z.string(), + mdfr: z.string(), +}); + +export const pbnstRegZod = z.object({ + pbnstRuseFcltPk: z.number().default(0), + swtrmtFcltFk: z.string(), + ruseUtztnFcltNm: z.string(), + fcltCpct: z.string(), + ruseCpct: z.string(), + splyExtraCpct: z.string(), + regDt: z.date().default(new Date()), + rgtr: z.string().default("test"), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string().default("test"), + fcFiles: z.array(fcFileSchema), + fcBizs: z.array(fcBizSchema), + fcOpers: z.array(fcOperSchema), +}); + +const pubHasuZod = z.object({ + bscFctCd: z.string(), + sido: z.string().default(""), + gugun: z.string().default(""), + bscFctNm: z.string().default(""), + efflWqltStndrdNm: z.string().default(""), + fctCpc: z.number().default(0), +}); + +export type pubHasuType = z.infer; + +//관경 제외 +export const exampleData = { + pbnstRuseFcltPk: 1, + swtrmtFcltFk: "SWTRMT-001", + ruseUtztnFcltNm: "재이용시설 A", + fcltCpct: "100", + ruseCpct: "90", + splyExtraCpct: "10", + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + fcFiles: [], + fcBizs: [ + { + pbnstRuseFcltBizPk: 10, + pbnstRuseFcltFk: 1, + cycl: "1", + seCd: "A010", + bizMthdCd: "M02", + instlAprvSncnDt: "2022-01-01", + bizCmcnDay: "2022-02-01", + gvsbs: "정부지원", + lcep: "지자체", + cusrAlotm: "고객", + etc: "비고 없음", + totalMoney: "100000000", + rprcsFcltCpct: "50", + majorPrcsMsrcCd: "MP01", + addr: "서울시 종로구", + rprcsMthdCd: "RP01", + inoutYn: "Y", + mainSplyPumpCpct: "30", + erctWtrOcrnCpct: "5", + erctUswtrLinkSpt: "있음", + erctUswtrFcltCpct: "20", + erctUswtrPrcsMeth: "생물학적", + erctUswtrPrcsMsrcCd: "EM01", + wwtEmsnFcltPrmsnYn: "Y", + tmsInstlYn: "N", + pbnstDrngInflwExclYn: "Y", + bod: "30", + grssClfg: "양호", + combResdch: "적정", + trbt: "10", + clIonQnt: "5", + smll: "없음", + crmty: "정상", + tph: "0.2", + tn: "2", + ph: "7.2", + cdtnv: "100", + designCst: "1000", + cstrnSpvsCst: "500", + fcltSbsdCst: "200", + wstCst: "300", + cnstCmcnCst: "1000", + mntrgEqpmntInstlCst: "150", + gisDbCst: "200", + elpwrMtrngCst: "180", + mchnCst: "700", + archCst: "400", + pplCst: "300", + ruseFcltCst: "5000", + designCstClcln: "990", + cstrnSpvsCstClcln: "480", + fcltSbsdCstClcln: "190", + wstCstClcln: "280", + cnstCmcnCstClcln: "980", + mntrgEqpmntInstlCstClcln: "140", + gisDbCstClcln: "190", + elpwrMtrngCstClcln: "170", + mchnCstClcln: "680", + archCstClcln: "380", + pplCstClcln: "290", + ruseFcltCstClcln: "4800", + fcOrgwts: [ + { + pbnstRuseFcltBizFk: 10, + swtrmtFcltFk: 1, + orgwtWtritQnt: "100", + tmsYn: "Y", + dschgFmYn: "N", + dtlPstnExpln: "배출 위치", + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + { + pbnstRuseFcltBizFk: 10, + swtrmtFcltFk: 2, + orgwtWtritQnt: "153", + tmsYn: "Y", + dschgFmYn: "N", + dtlPstnExpln: "배출 위치22", + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + ], + flg: "N", + regDt: "2022-01-01", + rgtr: "admin", + mdfcnDt: "2022-02-01", + mdfr: "admin", + }, + { + pbnstRuseFcltBizPk: 11, + pbnstRuseFcltFk: 1, + cycl: "2", + seCd: "A011", + bizMthdCd: "M02", + instlAprvSncnDt: "2022-01-01", + bizCmcnDay: "2022-02-01", + gvsbs: "민간", + lcep: "지자체", + cusrAlotm: "고객", + etc: "비고 없음", + totalMoney: "100000000", + rprcsFcltCpct: "50", + majorPrcsMsrcCd: "MP01", + addr: "부산시 해운대구", + rprcsMthdCd: "RP01", + inoutYn: "Y", + mainSplyPumpCpct: "30", + erctWtrOcrnCpct: "5", + erctUswtrLinkSpt: "있음", + erctUswtrFcltCpct: "20", + erctUswtrPrcsMeth: "생물학적", + erctUswtrPrcsMsrcCd: "EM01", + wwtEmsnFcltPrmsnYn: "Y", + tmsInstlYn: "N", + pbnstDrngInflwExclYn: "Y", + bod: "30", + grssClfg: "양호", + combResdch: "적정", + trbt: "10", + clIonQnt: "5", + smll: "없음", + crmty: "정상", + tph: "0.2", + tn: "2", + ph: "7.2", + cdtnv: "100", + designCst: "1000", + cstrnSpvsCst: "500", + fcltSbsdCst: "200", + wstCst: "300", + cnstCmcnCst: "1000", + mntrgEqpmntInstlCst: "150", + gisDbCst: "200", + elpwrMtrngCst: "180", + mchnCst: "700", + archCst: "400", + pplCst: "300", + ruseFcltCst: "5000", + designCstClcln: "990", + cstrnSpvsCstClcln: "480", + fcltSbsdCstClcln: "190", + wstCstClcln: "280", + cnstCmcnCstClcln: "980", + mntrgEqpmntInstlCstClcln: "140", + gisDbCstClcln: "190", + elpwrMtrngCstClcln: "170", + mchnCstClcln: "680", + archCstClcln: "380", + pplCstClcln: "290", + ruseFcltCstClcln: "4800", + fcOrgwts: [ + { + pbnstRuseFcltBizFk: 11, + swtrmtFcltFk: 1, + orgwtWtritQnt: "152", + tmsYn: "Y", + dschgFmYn: "N", + dtlPstnExpln: "배출 위치1", + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + { + pbnstRuseFcltBizFk: 11, + swtrmtFcltFk: 1, + orgwtWtritQnt: "150", + tmsYn: "Y", + dschgFmYn: "N", + dtlPstnExpln: "배출 위치", + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + ], + flg: "N", + regDt: "2022-01-01", + rgtr: "manager", + mdfcnDt: "2022-02-01", + mdfr: "manager", + }, + ], + fcOpers: [ + { + pbnstRuseFcltOperInfoPk: 100, + pbnstRuseFcltFk: 1, + operMthd: "위탁", + rprtvBzenty: "기관명", + bgngDt: new Date("2025-05-21T11:03:26.434810"), + endDt: new Date("2025-05-21T11:03:26.434810"), + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + { + pbnstRuseFcltOperInfoPk: 101, + pbnstRuseFcltFk: 1, + operMthd: "직영", + rprtvBzenty: "기관명", + bgngDt: new Date("2025-05-21T11:03:26.434810"), + endDt: new Date("2025-05-21T11:03:26.434810"), + regDt: new Date("2025-05-21T11:03:26.434810"), + rgtr: "admin", + mdfcnDt: new Date("2025-05-21T11:03:26.434810"), + mdfr: "admin", + }, + ], +}; diff --git a/apps/wr/components/lib/config/index.ts b/apps/wr/components/lib/config/index.ts index 4028f6cc3..0ed7b82dd 100644 --- a/apps/wr/components/lib/config/index.ts +++ b/apps/wr/components/lib/config/index.ts @@ -12,3 +12,5 @@ export const DEV_URL_FO = `http://con.mind-one.co.kr:${DEV_PORT_NEW}/api/v1`; +export const CS_URL= 'http://dev.onasys.co.kr:8000' +export const CS_TUS_UPLOAD= "/attach-service/api/v1/tus/upload"; \ No newline at end of file diff --git a/apps/wr/components/lib/useTus_wr/useTusWr.tsx b/apps/wr/components/lib/useTus_wr/useTusWr.tsx new file mode 100644 index 000000000..4aedb71d3 --- /dev/null +++ b/apps/wr/components/lib/useTus_wr/useTusWr.tsx @@ -0,0 +1,53 @@ +import { Upload, type HttpRequest, type HttpResponse, type OnSuccessPayload } from "tus-js-client"; +import { CS_TUS_UPLOAD, CS_URL } from "../config"; + +type UploadOptions = { + handleUploadStart?: (upload: Upload) => void; + handleProgress?: (percentage: string) => void; + handleSuccess?: (payload :OnSuccessPayload) => void; + handleResponse?: (req:HttpRequest, res: HttpResponse) => void; +}; + +export function TusClientUpload(oFile: File, setUpload: (upload: Upload) => void, options?: UploadOptions) { + const Authorization = "Authorization"; + const AUTH_USER_ID = "token-id"; + + //CS_URL + const uploader = new Upload(oFile, { + endpoint: 'http://localhost:3001' + CS_TUS_UPLOAD, + chunkSize: 10* 1024 * 1024, + headers: { + Authorization: "", + AUTH_USER_ID: "", + }, + metadata: { + filename: oFile.name, + filetype: oFile.type, + }, + onError(error) { + console.error(`Failed because: ${error}`); + }, + onProgress(bytesUploaded, bytesTotal) { + const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); + options?.handleProgress?.(percentage); + }, + onAfterResponse(req, res) { + const fileInfo = res.getHeader("X-File-Info"); + if (fileInfo === undefined || fileInfo === null) return; + + options?.handleResponse?.(res); + }, + onSuccess(payload :OnSuccessPayload) { + options?.handleSuccess?.(payload); + }, + }); + uploader.start(); + + options?.handleUploadStart?.(uploader); + + console.log("upload start >>>>>", uploader); + + + // setUpload(uploader); +} +// diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index 744e7bf4e..638f45915 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -303,8 +303,7 @@ export default function BdstReg({ form }: { form: any }) { selectClass={selectClass} selectArray={code.chBuCd} onSelectValue={val => f.onChange(val)} - value={f.value ?? code.chBuCd[0]?.val} - /> + value={f.value ?? code.chBuCd[0]?.val} className={""} label={""} /> )} /> diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index adba3284a..912d9dc77 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -2,15 +2,12 @@ import { SelectBox } from "@common/business_components"; import { - DatePicker, - FileUpload, FormUi, - UiTable, } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input, TableHead, TableRow } from "@common/components"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useState } from "react"; +import { use, useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { useWrStore } from "@/app/store"; @@ -21,7 +18,6 @@ import { import { commonButonSize, formH1Class, - formH2Class, formTableName, } from "@/components/lib/class/comClass"; import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail"; @@ -32,25 +28,22 @@ import { ruseFcltinfo, wasteWaterFcltINfo, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/headList"; +import { pbnstRegZod } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -const formSchema = z.object({ - username: z.string().min(2).max(50), - facilityName: z.string().min(2).max(50), -}); export function PbnstBuseForm() { - const { code, pubFac } = useWrStore((state) => state); - const { pubMngUpHeadList } = pubFac; + const { code, pbnst } = useWrStore((state) => state); + const { pubMngUpHeadList,pbnstBizCycle } = pbnst; + const [getBizCycle, setBizCycle] = useState(''); - const form = useForm>({ - resolver: zodResolver(formSchema), - defaultValues: { - username: "", - }, + + const form = useForm>({ + resolver: zodResolver(pbnstRegZod), + }); // 2. Define a submit handler. - function onSubmit(values: z.infer) { + function onSubmit(values: z.infer) { // Do something with the form values. // ✅ This will be type-safe and validated. console.log(values); @@ -62,6 +55,11 @@ export function PbnstBuseForm() { const [instlAprvDate, setInstlAprvDate] = useState(new Date()); const [bizCmcnDate, setBizCmcnDate] = useState(new Date()); const [files, setFiles] = useState(null); + useEffect(() => { + if (getBizCycle ) { + console.log("getBizCycle", getBizCycle); + } + }, [getBizCycle]); return (
@@ -76,108 +74,21 @@ export function PbnstBuseForm() {

등록차수

- ( - + 0 && pbnstBizCycle[0]? pbnstBizCycle[0].val : ""} className={""} selectClass={selectClass} - onSelectValue={() => {}} - {...field} - > - - )} - /> + onSelectValue={(val) => {setBizCycle}} + > + + +
- {/*
-

사업현황

-
- -
-
- ( - - {}} - /> - - )} - /> -
- -
- ( - - {}} - /> - - )} - /> -
-
- ( - - - - )} - /> -
-
- ( - - { - if (date) setInstlAprvDate(date); - }, - }} - mode="single" - {...field} - /> - - )} - /> -
-
*/} state); - const { pubMngUpHeadList, isInit } = pubFac; + const { pbnst } = useWrStore((state) => state); + const { pubMngUpHeadList, isInit } = pbnst; const [ruseOperData, setRuseOperData] = useState(); - const [files, setFiles] = useState(null); + const [planFiles, setPlanFiles] = useState(null); + const [relationfiles, setRelationFiles] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); + const [upload, setUpload] = useState(null); + const [progress, setProgress] = useState(0); + + const handleProgress = (percentage: string) => { + + console.log("handleProgress", percentage); + setProgress(Number(percentage)); + }; + const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { @@ -69,6 +85,35 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) { console.log(values); } + const testFile = () => { + if (relationfiles && relationfiles[0]) + TusClientUpload(relationfiles[0], setUpload, { + handleUploadStart: () => { + console.log("handleUploadStart"); + }, + handleProgress, + handleResponse: (req, res) => { + console.log(" handleResponse req", req); + console.log("handleResponse res", res); + }, + handleSuccess: (a) => { + console.log("req", a); + + }, + }); + }; + + useEffect(() => { + if (relationfiles && relationfiles[0]) + console.log("relationfiles ", relationfiles[0]); + + // TusClientUpload( + // relationfiles[0],{ + // handleUploadStart: setUpload, + // handleProgress, + // handleSuccess: setUpload, + // }) + }, [relationfiles]); const headMakeColSpan = (upHeadList: TableUpperProps[]) => { return ( <> @@ -127,26 +172,24 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) {
- -
-
- 재이용시설 운영정보 - -
- - - +
+
+ 재이용시설 운영정보 +
+ +

재이용수 공급 가능량

@@ -207,8 +250,8 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) { render={({}) => ( @@ -222,8 +265,8 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) { render={({}) => ( diff --git a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx index 5ebb88015..1256c0b56 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx @@ -85,10 +85,11 @@ export default function ChkgdExcel({ type }: { type: string }) { guide.utztnUsgCd === polution.utztnUsgCd ); + if (fusion) { return { ...guide, - rswtrPolutions: fusion?.rswtrPollutions, + rswtrPollutions: fusion?.rswtrPollutions, rswtrDetails:fusion?.rswtrDetails }; } else { @@ -104,10 +105,13 @@ export default function ChkgdExcel({ type }: { type: string }) { (item) => !guideKey.has(keyGenerator(item)) ); + const listTotalData:rswtChkZodType[] =[ ...totalData, ...onlypolution ] + + setExcelRswtData(listTotalData); } }); diff --git a/apps/wr/middleware.ts b/apps/wr/middleware.ts new file mode 100644 index 000000000..3ac0d64ed --- /dev/null +++ b/apps/wr/middleware.ts @@ -0,0 +1,50 @@ +import { NextRequest, NextResponse } from "next/server"; +import { CS_URL } from "./components/lib/config"; +//import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config"; + +const CLAIM_NAME = "Authorization" +const AUTH_USER_ID = "token-id" +const serverApiUrl = + CS_URL; +export function middleware(req: NextRequest) { + const pathname = req.nextUrl.pathname; + console.log(`[Middleware] Request URL: ${req.url}`); + const searchParams = req.nextUrl.searchParams; + + if (pathname.startsWith("/server")) { + const queryParams = searchParams.toString(); + const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${queryParams ? `?${queryParams}` : "" + }`; + console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`); + return NextResponse.rewrite(new URL(newUrl)); + } + + if (pathname.startsWith("/attach-service")) { + const requestHeaders = new Headers(req.headers); + const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJpYXQiOjE3NDc4MTM2MDksImV4cCI6MTc0NzgxMzkwOX0.XGiDHC-ljuEdN6M638q0nDet6XRQcO8o66LKvZZ07r4rGykn2ba8yagC_-8LVpVjrkPzIVZnW10I2fQWgAGT5Q" + const userId = 'a0ec7a07-752a-4f7f-89a6-854e63d2e3a0'; + //const token = req.cookies.get(CLAIM_NAME)?.value; + //const userId = req.cookies.get(AUTH_USER_ID)?.value; + const newUrl = `${serverApiUrl}${pathname}`; + + console.log("serverApiUrl ", serverApiUrl); + console.log("pathname ", pathname); + + + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + console.log( + `[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`, + ); + return NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + } + + return NextResponse.next(); +} + +export const config = { + matcher: ["/server/:path*", "/attach-service/:path*"], +}; diff --git a/apps/wr/package.json b/apps/wr/package.json index 54a7878b4..58a01dc42 100644 --- a/apps/wr/package.json +++ b/apps/wr/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { + "@common/assets": "workspace:*", "@common/business_components": "workspace:*", "@common/components": "workspace:*", - "@common/assets": "workspace:*", "@hookform/resolvers": "^4.1.3", "@tanstack/react-table": "^8.21.2", "class-variance-authority": "^0.7.1", @@ -22,6 +22,7 @@ "react-hot-toast": "^2.5.2", "tailwind-merge": "^3.0.1", "tailwindcss-animate": "^1.0.7", + "tus-js-client": "^4.3.1", "zod": "^3.24.2" }, "devDependencies": { diff --git a/apps/wr/public/sample_rs_chk.xlsx b/apps/wr/public/sample_rs_chk.xlsx index 1569fbbcee08b0054ed0c903dfba81442f1c7335..39b0e7d3e06f5465e249e88f44062522e776e65c 100644 GIT binary patch delta 6300 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