From 103c5e05aea8923687d8264678e230160b2a6c9e Mon Sep 17 00:00:00 2001 From: leedj312 Date: Wed, 28 May 2025 17:18:35 +0900 Subject: [PATCH] Co-authored-by: truthplumage --- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 43 ++++- .../ruseFcltMng/fcltReg/pbnstReg/type.tsx | 14 +- apps/wr/components/lib/api/index.ts | 99 ++++++----- apps/wr/components/lib/config/index.ts | 4 +- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 157 ++++++++++-------- apps/wr/middleware.ts | 2 +- 6 files changed, 187 insertions(+), 132 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 00b50d157..1693dbf16 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -1,6 +1,6 @@ import { z } from "zod"; import type { TableUpperProps } from "../rainReg"; -import { fetchType, getFetch, postFectch } from "@/components/lib/api"; +import { deleteFectch, fetchType, getFetch, postFectch } from "@/components/lib/api"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; import { exampleData, @@ -51,6 +51,8 @@ type pubFacActions = { pbnstRegSearch: (txt: string | undefined, sgg: string) => void; pbnstReg: (txt: string | undefined) => void; pbnstUpdate(pbnstRes: customPbnst) : Promise; + fileDelete:(atflCd:string)=>void + fileDownLoad: (atflCd: string) => void }; export type pubFacType = pubFacState & pubFacActions; @@ -151,9 +153,12 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { }, pbnstRegSearch: async (txt: string | undefined, sgg: string) => { try { + + const pbnstRes = await getFetch( "wr", - `/api/v1/reuseFc/pubFc` + (txt ? `/${txt}` : "") + `/${sgg}` + '' + // `/api/v1/prcsFclt/ruseInfo/${pageNo}/${pageCnt}/${searchingCd}/${nameCd}/${fcltCpct}/{oprtngSttsCd}/{bscFctClsCd}/{swtrmtFcltNm}` + (txt ? `/${txt}` : "") + `/${sgg}` ); // API 응답이 pbnstRegZod 타입의 단일 객체라고 가정 const pbnstBizCycle = @@ -205,16 +210,38 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } catch (error) { console.error("Error updating pbnst:", error); } - },fileDelete(atflCd:string){ + },fileDelete: async (atflCd:string)=>{ try { - const response = postFectch( - `/ratfl/attachments/atflCd/${atflCd}`, - null, - fetchType.COMMON + const response = await deleteFectch( + `/attach-service/api/v1/atfl/attachments/atflCd//${atflCd}`, + undefined, + fetchType.CS ); - return response; + + console.log("File deleted successfully:", response); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + isInit: false, + }, + }));; } catch (error) { + + console.error("Error deleting file:", error); + } + },fileDownLoad: async (atflCd: string) => { + + try{ + const response = await getFetch( fetchType.CS , `/api/v1/atflcd/download/${atflCd}`) + + + if (!response.ok) { + throw new Error(`Error downloading file: ${response.statusText}`); + } + }catch(error){ + console.error("Error downloading file:", error); } } }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index 29bec52b9..358986465 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -44,6 +44,8 @@ export type fcOrgwtType = z.infer; export type ppInstlType = z.infer; export type operType = z.infer; +export type fcFileType = z.infer; + const pplInstlSchema = z.object({ ruseFcltBizFk: z.string(), @@ -52,13 +54,13 @@ const pplInstlSchema = z.object({ 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()), + ruseFcltFk: z.number().default(0).nullish(), + fileTkn: z.string(), + filePath: z.string(), + fileKnd: z.string(), + regDt: z.date().default(new Date()).nullish(), rgtr: z.string(), - mdfcnDt: z.date().default(new Date()), + mdfcnDt: z.date().default(new Date()).nullish(), mdfr: z.string(), }); diff --git a/apps/wr/components/lib/api/index.ts b/apps/wr/components/lib/api/index.ts index 6e3b9b1a8..7b8507910 100644 --- a/apps/wr/components/lib/api/index.ts +++ b/apps/wr/components/lib/api/index.ts @@ -1,69 +1,84 @@ //8880 -import { DEV_URL_FO, DEV_URL_WR } from "../config/"; +import { CS_URL, DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/"; -export const fetchType={COMMON: "common", WR: "wr"} +export const fetchType = { COMMON: "common", WR: "wr", LOCAL: "LOCAL" , CS: "CS" }; -export const getFetch = async( type:string , url: string) => { - const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR - const response = await fetch( div+url , { +export const getFetch = async (type: string, url: string) => { + const div = + type === fetchType.COMMON + ? DEV_URL_FO + : type === fetchType.LOCAL + ? LOCAL_URL + : type === fetchType.CS + ? '' + : DEV_URL_WR; + + const response = await fetch(div + url, { method: "GET", headers: { - accept: "application/json", + accept: "application/json", }, }); - if(!response.ok) { + if (!response.ok) { throw new Error(`오류 발생: ${response.status}`); } - const res = await response.json() + const res = await response.json(); return res.data; -} +}; -export const postFectch = async (url: string, params: any , type?:string) => { - const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR +export const postFectch = async (url: string, params: any, type?: string) => { + const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR; - const response = await fetch(div+url, { + const response = await fetch(div + url, { method: "POST", headers: { - 'accept': 'application/json', + accept: "application/json", "Content-Type": "application/json", }, body: JSON.stringify(params), }); - if(!response.ok) { + if (!response.ok) { throw new Error(`오류 발생: ${response.status}`); } return await response.json(); -} - +}; export const putFectch = async (url: string, params: any) => { + const response = await fetch(DEV_URL_WR + url, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }); + if (!response.ok) { + throw new Error(`오류 발생: ${response.status}`); + } + return response; +}; - const response = await fetch(DEV_URL_WR+url, { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(params), - }); - if(!response.ok) { - throw new Error(`오류 발생: ${response.status}`); - } - return response; - } +export const deleteFectch = async (url: string, params?: any, type?: string) => { + const div = + type === fetchType.COMMON + ? DEV_URL_FO + : type === fetchType.LOCAL + ? LOCAL_URL + : type === fetchType.CS + ? '' + : DEV_URL_WR; - -export const deleteFectch = async (url: string, params: any) => { - const response = await fetch(DEV_URL_WR+url, { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(params), - }); - if(!response.ok) { - throw new Error(`오류 발생: ${response.status}`); - } - return response; - } \ No newline at end of file + console.log("deleteFectch url", div + url); + const response = await fetch(div + url, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: params?JSON.stringify(params):undefined, + }); + if (!response.ok) { + throw new Error(`오류 발생: ${response.status}`); + } + return await response.text(); +}; \ No newline at end of file diff --git a/apps/wr/components/lib/config/index.ts b/apps/wr/components/lib/config/index.ts index 1348c2dc1..d0e076d81 100644 --- a/apps/wr/components/lib/config/index.ts +++ b/apps/wr/components/lib/config/index.ts @@ -1,5 +1,5 @@ -const LOCAL_PORT = "3000"; +const LOCAL_PORT = "3001"; const DEV_PORT = "11080"; const DEV_PORT_NEW="11082" @@ -12,6 +12,6 @@ export const DEV_URL_WR = `http://con.mind-one.co.kr:${DEV_PORT}/api/v1`; export const DEV_URL_FO = `http://con.mind-one.co.kr:${DEV_PORT_NEW}/api/v1`; - +export const LOCAL_URL = `http://localhost:${LOCAL_PORT}`; 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/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index 6f0a1ac02..89343cb93 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -5,7 +5,7 @@ import { FileUpload, FormUi } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input } from "@common/components"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useRef, useState } from "react"; +import { use, useEffect, useRef, useState } from "react"; import { useFieldArray, useForm } from "react-hook-form"; import { z } from "zod"; @@ -20,25 +20,28 @@ import type { Upload } from "tus-js-client"; import { pbnstRegZod, type customPbnst, + type fcFileType, type operType, type ruseFcltType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; export type FilesType = { - atflCd: String; + atflCd: string; file: File; }; export function PbnstMngForm({ data }: { data: customPbnst }) { - const { pbnst, pbnstUpdate } = useWrStore((state) => state); + const { pbnst, pbnstUpdate, fileDelete } = useWrStore((state) => state); const { pbnstMngUpHeadList } = pbnst; const [ruseOperData, setRuseOperData] = useState(); - const [planFiles, setPlanFiles] = useState(null); + const [planFiles, setPlanFiles] = useState(null); const [relationfiles, setRelationFiles] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); + const [regFileList, setRegFileList] = useState(null); const [upload, setUpload] = useState(null); const [progress, setProgress] = useState(0); - + //const new File([] as BlobPart[], "") 파일 다운로드 활용 const handleProgress = (percentage: string) => { setProgress(Number(percentage)); }; @@ -58,6 +61,7 @@ export function PbnstMngForm({ data }: { data: customPbnst }) { name: "fcOpers", }); + const fileDownload = (index: number) => {}; const plusHist = () => { append({ choose: false, @@ -80,8 +84,6 @@ export function PbnstMngForm({ data }: { data: customPbnst }) { selectedIdxs.reverse().forEach((idx) => remove(idx)); }; - const onSelectValue = (val: string) => {}; - useEffect(() => { if (!data) return; form.reset(data); @@ -90,26 +92,37 @@ export function PbnstMngForm({ data }: { data: customPbnst }) { // 2. Define a submit handler. function onSubmit(values: z.infer) { - console.log("submit", values); - // pbnstUpdate(values); values.fcOpers = ref.current || []; + values.fcFiles = regFileList || []; console.log("form values:", values); pbnstUpdate(values); } - const fileHandler = (files: File[]) => { - console.log('fileHandler', files); - let setReFiles = [...(relationfiles || [])]; - if (files && (!relationfiles || relationfiles.length < files.length)) { + + const fileHandler = (files: File[], type: string) => { + console.log("fileHandler", files); + let fileList = [] as FilesType[]; + if (type === "relation" && relationfiles) { + fileList = relationfiles; + } else if (type === "plan" && planFiles) { + fileList = planFiles; + } + + let setReFiles = [...(fileList || [])]; + if (files && (!fileList || fileList.length < files.length)) { files.find((item) => { if ( - !relationfiles || - relationfiles?.findIndex((reFile) => reFile.file === item) < 0 + !fileList || + fileList?.findIndex((reFile) => reFile.file === item) < 0 ) { TusClientUpload({ atflCd: "", file: item }) .then((tusFile) => { - setReFiles.push({ atflCd: tusFile.atflCd, file: item }); - console.log("after async setReFiles", setReFiles); - setRelationFiles(setReFiles); + setReFiles.push({ + atflCd: tusFile.atflCd.toString(), + file: item, + }); + type === "relation" + ? setRelationFiles(setReFiles) + : setPlanFiles(setReFiles); }) .catch((e) => { console.log(e); @@ -117,47 +130,54 @@ export function PbnstMngForm({ data }: { data: customPbnst }) { return item; } }); - } else if ( - relationfiles && - (!files || relationfiles.length > files.length) - ) { + } else if (fileList && (!files || fileList.length > files.length)) { if (!files) { - //TODO: 파일삭제 + fileList.forEach((file) => { + fileDelete(file.atflCd as string); + }); setReFiles = []; setReFiles.length = 0; } else { - //TODO: 파일삭제 - relationfiles?.forEach((item, index) => { + fileList?.forEach((item, index) => { const idx = files?.indexOf(item.file); if (idx < 0) { - setReFiles.slice(index); + setReFiles.splice(index); + fileDelete(item.atflCd as string); } }); } - setRelationFiles(setReFiles) + type === "relation" + ? setRelationFiles(setReFiles) + : setPlanFiles(setReFiles); } }; + const regFileFilter=(files:FilesType[], fileKnd:string, regFile:fcFileType[])=>{ + const planDatas = regFile?.filter(item=>item.fileKnd!==fileKnd) || []; + const data = files.map((item) => ({ + fileTkn: item.atflCd, + filePath: item.file.name, + fileKnd: fileKnd, + rgtr: TEST_UUID, + mdfr: TEST_UUID, + })); + return [...planDatas, ...data] + } + useEffect(() => { + console.log("relationfiles:", relationfiles); + if (relationfiles) { + setRegFileList(regFileFilter(relationfiles, "계통도", regFileList||[])); + } + }, [relationfiles]); + useEffect(() => { + if (planFiles) { + setRegFileList(regFileFilter(planFiles, "평면도", regFileList||[])); + } + }, [planFiles]); useEffect(() => { - console.log("relationfiles changed:", relationfiles); - }, [relationfiles]); + console.log("regFileList:", regFileList); + }, [regFileList]); - 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(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); @@ -288,36 +308,27 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
- ( - - item.file) || []} - setFiles={(files: File[] | null) => { - if (files) fileHandler(files); - }} - fileTypes="PDF" - > - - )} - /> + + item.file) || []} + setFiles={(files: File[] | null) => { + if (files) fileHandler(files, "relation"); + }} + fileTypes="PDF" + onFileClick={(index) => {}} + > +
- ( - - - - )} - /> + + item.file) || []} + setFiles={(files: File[] | null) => { + if (files) fileHandler(files, "plan"); + }} + fileTypes="PDF" + > +
diff --git a/apps/wr/middleware.ts b/apps/wr/middleware.ts index fdd0a3c9c..e30e04f4d 100644 --- a/apps/wr/middleware.ts +++ b/apps/wr/middleware.ts @@ -21,7 +21,7 @@ export function middleware(req: NextRequest) { if (pathname.startsWith("/attach-service")) { const requestHeaders = new Headers(req.headers); - const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDgzOTk3ODl9.wbYXSIFNSvVJKyofFW0C3Yg99AZ99oLYSCMjcoRvZB6DqfxCbqxHPxUgwWyFE6oHJWYrX6q4BvMY2TdVOtzxnA" + const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDg0MjU0NzJ9.rABGFEzyCEDYwnuzd-6V0lPtckSGx-h77-tJBYFz00KPowmWBpwMLrSynxmHpmtmga86ksIYxuoMkiT1_aI6Sw" const userId = 'a0ec7a07-752a-4f7f-89a6-854e63d2e3a0' //const token = req.cookies.get(CLAIM_NAME)?.value; //const userId = req.cookies.get(AUTH_USER_ID)?.value;