This commit is contained in:
leedj312
2025-05-27 20:01:42 +09:00
co-authored by truthplumage
parent 299129a1f1
commit bd1f91c725
7 changed files with 253 additions and 99 deletions
@@ -43,12 +43,19 @@ export const pbnstDemandHeadListExport: TableUpperProps[] = [
export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [
{ id: "ruseUtztnFcltNm", title: "운영방식" },
{ id: "ruseUtztnFcltNm", title: "운영방식" },
{ id: "orgwtWtritQnt", title: "원수취수량" },
{ id: "tmsYn", title: "하수처리량TMS 전후", },
{ id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​", },
{ id: "dtlPstnExpln", title: "상세위치 설명", },
];
export const fcOrgwtsHeadListExport: TableUpperProps[] = [
{ id: "sido", title: "운영방식" },
{ id: "gugun", title: "원수취수량" },
{ id: "bscFctNm", title: "시설명" },
{ id: "addr", title: "상세위치 설명" },
]
export const pbnstMngNmExport: chHeadType[] = [
{ headNm: "upChangeRe", text: "운영대행기간", length: 2 },
@@ -124,4 +131,3 @@ export const ruseWaterQulityList:formDetailType[]=[
]
@@ -16,6 +16,7 @@ import {
pubFacHeadListExport,
pplInstlsHeadListExport,
pbnstDemandHeadListExport,
fcOrgwtsHeadListExport,
} from "./headList";
const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }];
@@ -25,6 +26,8 @@ const pbnstOrgwtHeadList = pbnstOrgwtHeadListRxport;
const pbnstMngNm = pbnstMngNmExport;
const pplInstlsHeadLisat = pplInstlsHeadListExport;
const pbnstDemandHeadList = pbnstDemandHeadListExport;
const fcOrgwtsHeadList=fcOrgwtsHeadListExport
export type pubFacState = {
pbnst: {
@@ -39,6 +42,7 @@ export type pubFacState = {
pbnstOrgwtHeadList: TableUpperProps[];
pplInstlsHeadLisat: TableUpperProps[];
pbnstDemandHeadList: TableUpperProps[];
fcOrgwtsHeadList: TableUpperProps[];
};
};
type pubFacActions = {
@@ -64,6 +68,7 @@ export const pubFacStateExport: pubFacState = {
selectLabel: selectLabel,
pplInstlsHeadLisat: pplInstlsHeadLisat,
pbnstDemandHeadList: pbnstDemandHeadList,
fcOrgwtsHeadList: fcOrgwtsHeadList,
},
};
+49 -39
View File
@@ -1,53 +1,63 @@
import { Upload, type HttpRequest, type HttpResponse, type OnSuccessPayload } 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: HttpResponse) => 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";
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.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);
//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;
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?.handleResponse?.(res);
},
onSuccess(payload :OnSuccessPayload) {
options?.handleSuccess?.(payload);
},
options?.handleUploadStart?.(uploader);
uploader.start();
console.log("upload start >>>>>", uploader);
// setUpload(uploader);
});
uploader.start();
options?.handleUploadStart?.(uploader);
console.log("upload start >>>>>", uploader);
// setUpload(uploader);
}
//
//
@@ -1,12 +1,16 @@
"use client";
import { SelectBox } from "@common/business_components";
import { FormUi, type SelectDataType } from "@common/business_components/ui";
import {
FormUi,
UiModal,
type SelectDataType,
} from "@common/business_components/ui";
import { Form, FormField } from "@common/business_components/ui/form";
import { Button, Input, Label, TableHead, TableRow } from "@common/components";
import { zodResolver } from "@hookform/resolvers/zod";
import { use, useEffect, useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import { set, useFieldArray, useForm } from "react-hook-form";
import { z } from "zod";
import { useWrStore } from "@/app/store";
import {
@@ -35,6 +39,7 @@ import {
type ppInstlType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
import FcOrgwtsRegModal from "@/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal";
export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
const { code, pbnst } = useWrStore((state) => state);
@@ -43,6 +48,10 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
const [ppiSelectList, setPpiSelectList] =
useState<[{ name: string; val: SelectDataType[] }]>();
const [ppiYn, setPpiYn] = useState("Y");
const [ isFcOrgwts, setIsFcOrgwts] = useState<boolean>(false);
const form = useForm<fcBizType>({
resolver: zodResolver(fcBizSchema),
});
@@ -61,6 +70,19 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
control: form.control,
name: "pplInstls",
});
const fcOrgwtsReg = () =>{
console.log("fcOrgwtsReg");
//ref로바꿔야함
setFcOrgwts({isOpen:true , data:fcOrgwtFiled as fcOrgwtType[]});
}
useEffect(() => {
if (data) {
const index = Number(getBizCycle) - 1;
@@ -114,7 +136,7 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
}}
></SelectBox>
<Button size={commonButonSize}>저장</Button>
<Button type ="submit" size={commonButonSize}>저장</Button>
</div>
</div>
<MngRegFormDetail
@@ -156,7 +178,7 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
<h1 className={formH1Class}>재이용 원수취수 현황</h1>
<div>
<Button size={commonButonSize}>추가등록</Button>
<Button type="button" onClick={() => {setIsFcOrgwts(true)} }size={commonButonSize}>추가등록</Button>
<RuseMngTable
tableData={fcOrgwtFiled}
headList={pbnst.pbnstOrgwtHeadList}
@@ -213,6 +235,13 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
</form>
</Form>
</div>
<UiModal
open={isFcOrgwts}
onOpenChange={(open: boolean) => setIsFcOrgwts(open)}
bodyClass={"w-[68vw] max-w-none h-[60vh]"}
body={<FcOrgwtsRegModal></FcOrgwtsRegModal>}
></UiModal>
</div>
);
}
@@ -23,33 +23,37 @@ import {
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr";
import type { Upload } from "tus-js-client";
import { pbnstRegZod, type customPbnst, type operType, type ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import {
pbnstRegZod,
type customPbnst,
type operType,
type ruseFcltType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
export type FilesType = {
atflCd: String;
file: File;
};
export function PbnstMngForm({ data }: { data: customPbnst }) {
const { pbnst ,pbnstUpdate} = useWrStore((state) => state);
const { pbnstMngUpHeadList} = pbnst;
const { pbnst, pbnstUpdate } = useWrStore((state) => state);
const { pbnstMngUpHeadList } = pbnst;
const [ruseOperData, setRuseOperData] = useState<operType[]>();
const [planFiles, setPlanFiles] = useState<File[] | null>(null);
const [relationfiles, setRelationFiles] = useState<File[] | null>(null);
const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [upload, setUpload] = useState<Upload | null>(null);
const [progress, setProgress] = useState(0);
const handleProgress = (percentage: string) => {
setProgress(Number(percentage));
};
const ref = useRef<operType[] | null>(data.fcOpers ?? null);
const form = useForm<z.infer<typeof pbnstRegZod>>({
resolver: zodResolver(pbnstRegZod),
defaultValues: pbnstRegZod.parse({}),
});
const { fields: fcOpersField } = useFieldArray({
control: form.control,
name: "fcOpers",
@@ -58,51 +62,56 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
const onSelectValue = (val: string) => {};
useEffect(() => {
form.reset(data);
setRuseOperData(data.fcOpers);
form.reset(data);
setRuseOperData(data.fcOpers);
}, [data]);
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof pbnstRegZod>) {
console.log("submit",values);
pbnstUpdate(values);
console.log("submit", values);
testFile;
// pbnstUpdate(values);
}
const fileHandler = (files:File[]) => {
const setReFiles = [...(relationfiles || [])];
if (files && (!relationfiles || files?.length > relationfiles?.length)) {
files?.forEach( async (item) => {
if (
relationfiles &&
relationfiles?.filter((reFile) => reFile.file.name == item.name)
?.length > 0
) {
return;
} else {
const tusFile= await TusClientUpload({ atflCd: "", file: item })
setReFiles.push({ atflCd: tusFile.atflCd, file: item });
}
});
} else if (
relationfiles &&
(!files || relationfiles.length > files.length)
) {
if (!files) {
setReFiles.length = 0;
} else {
relationfiles?.forEach((item, index) => {
const idx = files?.indexOf(item.file);
if (idx < 0) {
setReFiles.slice(index);
}
});
}
}
setRelationFiles(setReFiles);
};
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);
},
});
TusClientUpload(relationfiles[0], setUpload);
};
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
useEffect(() => {
if (relationfiles && relationfiles[0])
console.log("relationfiles ", relationfiles[0]);
// TusClientUpload(
// relationfiles[0],{
// handleUploadStart: setUpload,
// handleProgress,
// handleSuccess: setUpload,
// })
}, [relationfiles]);
return (
<div className=" !mx-[1.6rem] !p-0r">
<div>
@@ -113,11 +122,16 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
<h2 className={formTableName + "pr-3 col-span-10 "}>
재이용 시설명
</h2>
<span className="mt-4 ml-2">{form.getValues("ruseUtztnFcltNm") ? ": " + form.getValues("ruseUtztnFcltNm") : ""}</span>
<span className="mt-4 ml-2">
{form.getValues("ruseUtztnFcltNm")
? ": " + form.getValues("ruseUtztnFcltNm")
: ""}
</span>
</div>
<Button type="submit" size={commonButonSize}>저장</Button>
<Button type="submit" size={commonButonSize}>
저장
</Button>
</div>
<div>
@@ -150,7 +164,12 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
name="fcltCpct"
render={({ field }) => (
<FormUi label="시설용량(m³/일)">
<Input placeholder="" type="number" onChange={field.onChange} value={field.value} />
<Input
placeholder=""
type="number"
onChange={field.onChange}
value={field.value}
/>
</FormUi>
)}
/>
@@ -161,7 +180,12 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
name="hasuhasu"
render={({ field }) => (
<FormUi label="하수처리량(m³/일)">
<Input placeholder="" type="number" onChange={field.onChange} value={field.value} />
<Input
placeholder=""
type="number"
onChange={field.onChange}
value={field.value}
/>
</FormUi>
)}
/>
@@ -172,7 +196,12 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
name="ruseCpct"
render={({ field }) => (
<FormUi label="재이용량(m³/일)">
<Input placeholder="" type="number" onChange={field.onChange} value={field.value} />
<Input
placeholder=""
type="number"
onChange={field.onChange}
value={field.value}
/>
</FormUi>
)}
/>
@@ -183,7 +212,12 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
name="splyExtraCpct"
render={({ field }) => (
<FormUi label="공급여유량(m³/일)">
<Input placeholder="" type="number"onChange={field.onChange} value={field.value} />
<Input
placeholder=""
type="number"
onChange={field.onChange}
value={field.value}
/>
</FormUi>
)}
/>
@@ -200,8 +234,11 @@ export function PbnstMngForm({ data }: { data: customPbnst }) {
render={({}) => (
<FormUi label="계통도">
<FileUpload
files={relationfiles || []}
setFiles={setRelationFiles}
files={relationfiles?.map((item) => item.file) || []}
setFiles={
(files: File[] | null) => {
if(files)fileHandler(files)
} }
fileTypes="PDF"
></FileUpload>
</FormUi>
@@ -0,0 +1,64 @@
"use client";
import { useWrStore } from "@/app/store";
import { Title, UiTable } from "@common/business_components/ui";
import { ArrowLeft, ArrowRight } from "lucide-react";
import { useEffect, useState } from "react";
export default function FcOrgwtsRegModal() {
const { code, pbnst } = useWrStore((state) => state);
const { fcOrgwtsHeadList } = pbnst;
const [isFcOrgwtsData, setIsFcOrgwtsData] = useState<boolean>(false);
useEffect(() => {
console.log("isFcOrgwtsData", isFcOrgwtsData);
}, [isFcOrgwtsData]);
return (
<>
<div className="flex flex-col h-full">
<div>
<Title title={"취수하수처리장 추가"} />
</div>
<div className="flex flex-row flex-grow gap-4 mt-4">
<div className="w-3/7">
<UiTable
headName={"공공하수처리시설 목록"}
tableData={[]}
headlist={fcOrgwtsHeadList}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}
></UiTable>
</div>
<div className="flex flex-col items-center justify-center w-1/7 gap-2">
<ArrowRight
type="button"
onClick={() => {
setIsFcOrgwtsData(!isFcOrgwtsData);
}}
className="w-12 h-12 text-gray-500"
/>
<ArrowLeft className="w-12 h-12 text-gray-500" />
</div>
{/* Right Table container: Takes 2/5 of the width */}
<div className="w-3/7">
<UiTable
headName={"취수하수처리장 목록"}
tableData={[]}
headlist={fcOrgwtsHeadList}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}
></UiTable>
</div>
</div>
</div>
</>
);
}
+5 -2
View File
@@ -21,16 +21,18 @@ export function middleware(req: NextRequest) {
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 = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDgzNTA2NjV9.fzXqA7vfeOp9z7AC33urbh_hZqNPyadmrp0LAs62Ay5PcP2SiFX3smRTdLH6xQSYNtV5MNgKPvebU2VgPuhHIw"
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);
//wr:dev: pathname /attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
//http://dev.onasys.co.kr:8000/attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
if (token) requestHeaders.set(CLAIM_NAME, token);
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
@@ -48,3 +50,4 @@ export function middleware(req: NextRequest) {
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*"],
};