This commit is contained in:
leedj312
2025-05-28 13:10:21 +09:00
co-authored by truthplumage
parent 2b582ed2cf
commit 7c920303ae
6 changed files with 143 additions and 102 deletions
@@ -205,6 +205,17 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
} catch (error) {
console.error("Error updating pbnst:", error);
}
},
},fileDelete(atflCd:string){
try {
const response = postFectch(
`/ratfl/attachments/atflCd/${atflCd}`,
null,
fetchType.COMMON
);
return response;
} catch (error) {
}
}
};
};
+66 -51
View File
@@ -1,63 +1,78 @@
import { Upload, type HttpRequest, type HttpResponse, type OnSuccessPayload } from "tus-js-client";
import {
Upload,
type HttpRequest,
type HttpResponse,
type OnSuccessPayload,
type DetailedError,
} from "tus-js-client";
import { CS_TUS_UPLOAD, CS_URL } from "../config";
import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
type UploadOptions = {
handleUploadStart?: (upload: Upload) => void;
handleProgress?: (percentage: string) => void;
handleSuccess?: (payload :OnSuccessPayload) => void;
handleResponse?: (req:HttpRequest, res: ReturnFileType) => void;
handleSuccess?: (payload: OnSuccessPayload) => void;
handleResponse?: (req: HttpRequest, res: ReturnFileType) => void;
};
export type ReturnFileType={
atflCd:String,
atflSn:number,
atflId:String,
physFileNm:String
}
export const TusClientUpload = (oFile: FilesType, options?: UploadOptions): Promise<ReturnFileType> => {
return new Promise((resolve, reject) => {
const Authorization = "Authorization";
const AUTH_USER_ID = "token-id";
//CS_URL
const uploader = new Upload(oFile.file, {
endpoint: 'http://localhost:3001' + CS_TUS_UPLOAD,
chunkSize: 10 * 1024 * 1024,
headers: {
Authorization: "",
AUTH_USER_ID: "",
},
metadata: {
filename: oFile.file.name,
filetype: oFile.file.type,
},
onError(error) {
console.error(`Failed because: ${error}`);
reject(error);
},
onProgress(bytesUploaded, bytesTotal) {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
console.log(`Uploaded ${bytesUploaded} of ${bytesTotal} bytes (${percentage}%)`);
options?.handleProgress?.(percentage);
},
onAfterResponse(req, res: HttpResponse) {
const fileInfo = res.getHeader("X-File-Info");
if (fileInfo === undefined || fileInfo === null) return;
console.log("onAfterResponse fileInfo", fileInfo);
resolve(JSON.parse(fileInfo) as ReturnFileType);
},
onSuccess(payload: OnSuccessPayload) {
options?.handleSuccess?.(payload);
},
});
options?.handleUploadStart?.(uploader);
uploader.start();
console.log("upload start >>>>>", uploader);
export type ReturnFileType = {
orgnlFileNm: string;
atflFlieSz: number;
atflType: string;
dwnldNocs: number;
delYn: string;
lnkgDmnId: string | null;
lnkgDmnNm: string | null;
regDt: Date | null;
atflCd: String;
atflSn: number;
atflId: String;
physFileNm: String;
};
export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) =>
new Promise<ReturnFileType>((resolve, reject) => {
try {
const Authorization = "Authorization";
const AUTH_USER_ID = "token-id";
let fileInfo: string | undefined;
//CS_URL
const uploader = new Upload(oFile.file, {
endpoint: CS_TUS_UPLOAD,
chunkSize: 10 * 1024 * 1024,
headers: {
Authorization: "",
AUTH_USER_ID: "",
},
metadata: {
filename: oFile.file.name,
filetype: oFile.file.type,
},
onError(error) {
reject(error);
},
onProgress(bytesUploaded, bytesTotal) {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
options?.handleProgress?.(percentage);
},
onAfterResponse(req, res: HttpResponse) {
fileInfo = res.getHeader("X-File-Info");
if (fileInfo === undefined || fileInfo === null) return;
},
onSuccess(payload: OnSuccessPayload) {
options?.handleSuccess?.(payload);
if (fileInfo) {
console.log('fileInfo', fileInfo);
resolve(JSON.parse(fileInfo) as ReturnFileType);
} else reject({} as DetailedError);
},
});
options?.handleUploadStart?.(uploader);
uploader.start();
} catch (e) {
console.log(e);
reject(e as DetailedError);
}
// setUpload(uploader);
});
}
//
//
@@ -12,7 +12,7 @@ import { z } from "zod";
import {
commonButonSize,
formH1Class,
formTableName
formTableName,
} from "@/components/lib/class/comClass";
import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr";
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
@@ -49,8 +49,11 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
defaultValues: pbnstRegZod.parse({}),
});
const { fields: fcOpersField, append, remove } = useFieldArray({
const {
fields: fcOpersField,
append,
remove,
} = useFieldArray({
control: form.control,
name: "fcOpers",
});
@@ -70,18 +73,17 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
};
const removeSelected = () => {
console.log("ref", ref.current);
console.log("fcOpersField", fcOpersField);
if(!ref.current) return;
if (!ref.current) return;
const selectedIdxs = ref.current
.map((item, idx) => (item.choose ? idx : -1))
.filter(idx => idx !== -1);
selectedIdxs.reverse().forEach(idx => remove(idx));
.map((item, idx) => (item.choose ? idx : -1))
.filter((idx) => idx !== -1);
selectedIdxs.reverse().forEach((idx) => remove(idx));
};
const onSelectValue = (val: string) => {};
useEffect(() => {
if (!data) return;
form.reset(data);
setRuseOperData(data.fcOpers);
}, [data]);
@@ -89,25 +91,30 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof pbnstRegZod>) {
console.log("submit", values);
testFile;
// pbnstUpdate(values);
values.fcOpers = ref.current || [];
console.log("form values:", values);
pbnstUpdate(values);
}
const fileHandler = (files:File[]) => {
const setReFiles = [...(relationfiles || [])];
if (files && (!relationfiles || files?.length > relationfiles?.length)) {
files?.forEach( async (item) => {
const fileHandler = (files: File[]) => {
console.log('fileHandler', files);
let setReFiles = [...(relationfiles || [])];
if (files && (!relationfiles || relationfiles.length < files.length)) {
files.find((item) => {
if (
relationfiles &&
relationfiles?.filter((reFile) => reFile.file.name == item.name)
?.length > 0
!relationfiles ||
relationfiles?.findIndex((reFile) => reFile.file === item) < 0
) {
return;
} else {
const tusFile= await TusClientUpload({ atflCd: "", file: item })
setReFiles.push({ atflCd: tusFile.atflCd, file: item });
TusClientUpload({ atflCd: "", file: item })
.then((tusFile) => {
setReFiles.push({ atflCd: tusFile.atflCd, file: item });
console.log("after async setReFiles", setReFiles);
setRelationFiles(setReFiles);
})
.catch((e) => {
console.log(e);
});
return item;
}
});
} else if (
@@ -115,8 +122,11 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
(!files || relationfiles.length > files.length)
) {
if (!files) {
//TODO: 파일삭제
setReFiles = [];
setReFiles.length = 0;
} else {
//TODO: 파일삭제
relationfiles?.forEach((item, index) => {
const idx = files?.indexOf(item.file);
if (idx < 0) {
@@ -124,9 +134,14 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
}
});
}
setRelationFiles(setReFiles)
}
setRelationFiles(setReFiles);
};
useEffect(() => {
console.log("relationfiles changed:", relationfiles);
}, [relationfiles]);
const testFile = () => {
// if (relationfiles && relationfiles[0])
// TusClientUpload(relationfiles[0], setUpload, {
@@ -140,7 +155,6 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
// },
// handleSuccess: (a) => {
// console.log("req", a);
// },
// });
};
@@ -168,7 +182,6 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
<Button type="submit" size={commonButonSize}>
저장
</Button>
</div>
<div>
@@ -176,22 +189,22 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
<div className="flex justify-between items-center mx-3 mb-3">
<span className={formTableName}>재이용시설 운영정보</span>
<div>
<Button
type="button"
size={commonButonSize}
className="!text-xl"
onClick={plusHist}
>
추가등록
</Button>
<Button
type="button"
size={commonButonSize}
className="!text-xl !bg-red-500 !text-white ml-1"
onClick={removeSelected}
>
삭제
</Button>
<Button
type="button"
size={commonButonSize}
className="!text-xl"
onClick={plusHist}
>
추가등록
</Button>
<Button
type="button"
size={commonButonSize}
className="!text-xl !bg-red-500 !text-white ml-1"
onClick={removeSelected}
>
삭제
</Button>
</div>
</div>
<RuseMngTable
@@ -282,10 +295,9 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
<FormUi label="계통도">
<FileUpload
files={relationfiles?.map((item) => item.file) || []}
setFiles={
(files: File[] | null) => {
if(files)fileHandler(files)
} }
setFiles={(files: File[] | null) => {
if (files) fileHandler(files);
}}
fileTypes="PDF"
></FileUpload>
</FormUi>
+1 -1
View File
@@ -21,7 +21,7 @@ export function middleware(req: NextRequest) {
if (pathname.startsWith("/attach-service")) {
const requestHeaders = new Headers(req.headers);
const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDgzNTA2NjV9.fzXqA7vfeOp9z7AC33urbh_hZqNPyadmrp0LAs62Ay5PcP2SiFX3smRTdLH6xQSYNtV5MNgKPvebU2VgPuhHIw"
const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDgzOTk3ODl9.wbYXSIFNSvVJKyofFW0C3Yg99AZ99oLYSCMjcoRvZB6DqfxCbqxHPxUgwWyFE6oHJWYrX6q4BvMY2TdVOtzxnA"
const userId = 'a0ec7a07-752a-4f7f-89a6-854e63d2e3a0'
//const token = req.cookies.get(CLAIM_NAME)?.value;
//const userId = req.cookies.get(AUTH_USER_ID)?.value;
@@ -45,7 +45,7 @@ export const FileUpload =
files.map((file:File, i:number) => (
<FileUploaderItem key={i} index={i}>
<Paperclip className="h-4 w-4 stroke-current" />
<span>{file.name}</span>
<span className="w-4/5 overflow-hidden">{file.name}</span>
</FileUploaderItem>
))}
</FileUploaderContent>
@@ -271,7 +271,7 @@ export const FileUploaderContent = forwardRef<
{...props}
ref={ref}
className={cn(
"flex rounded-xl gap-1",
"w-full flex rounded-xl gap-1",
orientation === "horizontal" ? "flex-raw flex-wrap" : "flex-col",
className,
)}
@@ -295,22 +295,25 @@ export const FileUploaderItem = forwardRef<
ref={ref}
className={cn(
buttonVariants({ variant: "ghost" }),
"h-6 p-1 justify-between cursor-pointer relative",
"h-6 p-1 justify-between cursor-pointer relative w-full",
className,
isSelected ? "bg-muted" : "",
)}
{...props}
onClick={() =>{
console.log('onclick');
removeFileFromSet(index)}}
>
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full w-full">
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden ">
{children}
</div>
<button
type="button"
className={cn(
"absolute",
"!w-1/5 z-50",
direction === "rtl" ? "top-1 left-1" : "top-1 right-1",
)}
onClick={() => removeFileFromSet(index)}
>
<span className="sr-only">remove item {index}</span>
<RemoveIcon className="w-4 h-4 hover:stroke-destructive duration-200 ease-in-out" />