Merge commit 'b42d518ecf3605c250aadbd9eb4f79e259aeb708' into iipbs/dm/dev
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
"use client";
|
||||
/**
|
||||
* 재이용실적등록 > 지도점검결과등록
|
||||
*/
|
||||
|
||||
"use client";
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
@@ -43,25 +47,25 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function Page() {
|
||||
const {
|
||||
auth,
|
||||
code,
|
||||
rainChkgdn,
|
||||
rswtChkgdn,
|
||||
rainChkInit,
|
||||
rainChkDetilUpdate,
|
||||
rainChkDelete,
|
||||
rainChkExcelDownload,
|
||||
rainChkHeadChange,
|
||||
rainChkNmSearch,
|
||||
isRainSttn,
|
||||
rswtChkgdnInit,
|
||||
rswtChkNmSearch,
|
||||
rswtChkPolInit,
|
||||
rswtChkDetilsUpdate,
|
||||
rswtChkDelete,
|
||||
rswtrChkExcelDownload,
|
||||
rswtChkHeadChange,
|
||||
getLaeSeCdCheck
|
||||
auth, // 사용자 권한 및 로그인 사용자 기준 정보
|
||||
code, // 공통 코드 및 지역 코드 정보
|
||||
rainChkgdn, // 빗물이용시설 지도점검 화면 상태
|
||||
rswtChkgdn, // 중수도시설 지도점검 화면 상태
|
||||
rainChkInit, // 빗물이용시설 지도점검 목록 초기 조회
|
||||
rainChkDetilUpdate, // 빗물이용시설 지도점검 상세 수정 저장
|
||||
rainChkDelete, // 빗물이용시설 지도점검 선택 건 삭제
|
||||
rainChkExcelDownload, // 빗물이용시설 지도점검 엑셀 양식/데이터 조회
|
||||
rainChkHeadChange, // 빗물이용시설 테이블 헤더 선택 상태 변경
|
||||
rainChkNmSearch, // 빗물이용시설명으로 목록 조회
|
||||
isRainSttn, // 빗물이용시설 상세/선택 상태 초기화
|
||||
rswtChkgdnInit, // 중수도시설 지도점검 목록 초기 조회
|
||||
rswtChkNmSearch, // 중수도시설명으로 목록 조회
|
||||
rswtChkPolInit, // 중수도 시설구분 변경 시 조회조건 초기화
|
||||
rswtChkDetilsUpdate, // 중수도시설 지도점검 상세 수정 저장
|
||||
rswtChkDelete, // 중수도시설 지도점검 선택 건 삭제
|
||||
rswtrChkExcelDownload, // 중수도시설 지도점검 엑셀 양식/데이터 조회
|
||||
rswtChkHeadChange, // 중수도시설 테이블 헤더 선택 상태 변경
|
||||
getLaeSeCdCheck // 사용자 관할 기관 코드 조회
|
||||
} = useWrStore((state) => {
|
||||
return state;
|
||||
});
|
||||
@@ -83,12 +87,13 @@ export default function Page() {
|
||||
String(new Date().getFullYear())
|
||||
);
|
||||
|
||||
const useInitRef = useRef(false);
|
||||
// laeSeCd가 아직 준비되기 전 초기 렌더에서 rainChkInit, rswtChkgdnInit 같은 초기 조회 로직이 먼저 도는 것을 막는다.
|
||||
const useInitRef = useRef(false); //초기 마운트가 한 번 끝났는지
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getLaeSeCdCheck();
|
||||
useInitRef.current = true;
|
||||
useInitRef.current = true; // getLaeSeCdCheck()를 호출한 뒤 true로 바뀜
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -111,8 +116,8 @@ export default function Page() {
|
||||
} else { // 중수도
|
||||
if (fcltNm) {
|
||||
rswtChkNmSearch(
|
||||
rainPageNation,
|
||||
rainPageSize,
|
||||
rswtPageNation,
|
||||
rswtPageSize,
|
||||
searchYear,
|
||||
laeSeCd,
|
||||
fcltNm
|
||||
@@ -145,7 +150,7 @@ export default function Page() {
|
||||
if (fcltNm) {
|
||||
rswtChkNmSearch(
|
||||
pageNo,
|
||||
rainPageSize,
|
||||
rswtPageSize,
|
||||
searchYear,
|
||||
laeSeCd,
|
||||
fcltNm
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
"use client";
|
||||
/**
|
||||
* 재이용실적등록 > 하수재이용실적등록
|
||||
*/
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
|
||||
@@ -15,7 +18,7 @@ import {
|
||||
yearOptions,
|
||||
} from "@/components/lib/func/common";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { InputTableBody } from "@/components/lib/func/TableData";
|
||||
import { pbnstTableBody } from "@/components/lib/func/TableData";
|
||||
import PbnPrfExcelModal from "@/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal";
|
||||
import {
|
||||
ContentsDiv,
|
||||
@@ -355,7 +358,7 @@ export default function PrfmncPrfmncReg() {
|
||||
{headMakeprfmnc(monthHeadList, [])}
|
||||
</TableHeader>
|
||||
<TableBody key={prfmnc.pageKey + "pageKey"}>
|
||||
{InputTableBody(
|
||||
{pbnstTableBody(
|
||||
inputData ?? [],
|
||||
monthHeadList,
|
||||
setInputData,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType,
|
||||
import { excelPrfmncSttnParsing } from "@/app/store/prfmncSttn/pbnstPrfmncSttn/excel";
|
||||
import { excelDownloadNumStyle, yearOptions } from "@/components/lib/func/common";
|
||||
import { type SheetParameter } from "@common/business_components/ui";
|
||||
import { InputTableBody } from "@/components/lib/func/TableData";
|
||||
import { pbnstTableBody } from "@/components/lib/func/TableData";
|
||||
import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SearchBaseForm, SearchInput, SelectBox, UiTable, type ChartConfig, type ReturnType } from "@common/business_components";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Label, Table, TableBody, TableHeader } from "@common/components/ui";
|
||||
@@ -714,8 +714,8 @@ export default function PbnstPrfmncSttn() {
|
||||
{headMakeprfmnc(monthHeadList, [])}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{/* {InputTableBody(prfData ?? [], monthHeadList, setPrfData)} */}
|
||||
{InputTableBody(prfData ?? [], monthHeadList, setPrfData, false)}
|
||||
{/* {pbnstTableBody(prfData ?? [], monthHeadList, setPrfData)} */}
|
||||
{pbnstTableBody(prfData ?? [], monthHeadList, setPrfData, false)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
|
||||
@@ -137,68 +137,25 @@ export const rainSplHeadNmExport: chHeadType[] = [
|
||||
];
|
||||
|
||||
export const rainChkgdnHeadListExport: TableUpperProps[] = [
|
||||
{ id: "order", title: "순번", mergeCell: true },
|
||||
{ id: "checkBox", title: "선택", mergeCell: true },
|
||||
{ id: "cityText", title: "시도", mergeCell: true },
|
||||
{ id: "sggText", title: "시군구", mergeCell: true },
|
||||
{ id: "bdstNm", title: "시설명", mergeCell: true },
|
||||
{ id: "operMngCdText", title: "운영관리형태", mergeCell: true },
|
||||
{ id: "oilqMeasMthdText", title: "유량측정방법", mergeCell: true },
|
||||
{ id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true },
|
||||
{ id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true },
|
||||
{ id: "chckYmd", title: "점검일", mergeCell: true },
|
||||
{ id: "utztnUsgCdText", title: "이용용도" },
|
||||
{ id: "totalSplyUswtrUtztnQnt", title: "연간대체수이용량(m³)" },
|
||||
{ id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)" },
|
||||
{
|
||||
id: "ph",
|
||||
title: "수소이온농도(pH)",
|
||||
upName: "useQuilty",
|
||||
upSequnce: 1,
|
||||
type: "number",
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "trbt",
|
||||
title: "탁도(NTU)",
|
||||
upName: "useQuilty",
|
||||
upSequnce: 2,
|
||||
type: "number",
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "grssClfg",
|
||||
title: "총대장균군수(개/mg)",
|
||||
upName: "useQuilty",
|
||||
upSequnce: 3,
|
||||
type: "number",
|
||||
edit: true,
|
||||
},
|
||||
|
||||
{
|
||||
id: "vltnDt",
|
||||
title: "부과일(위반일)",
|
||||
upName: "feeHist",
|
||||
upSequnce: 1,
|
||||
type: "text",
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "vltnMttr",
|
||||
title: "위반사항",
|
||||
upName: "feeHist",
|
||||
upSequnce: 2,
|
||||
type: "text",
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "levyAmt",
|
||||
title: "부과금액(천원)",
|
||||
upName: "feeHist",
|
||||
upSequnce: 3,
|
||||
type: "text",
|
||||
edit: true,
|
||||
},
|
||||
{ id: "order", title: "순번", mergeCell: true, widthPercent: 4 },
|
||||
{ id: "checkBox", title: "선택", mergeCell: true, widthPercent: 4 },
|
||||
{ id: "cityText", title: "시도", mergeCell: true, widthPercent: 5 },
|
||||
{ id: "sggText", title: "시군구", mergeCell: true, widthPercent: 5 },
|
||||
{ id: "bdstNm", title: "시설명", mergeCell: true, widthPercent: 7 },
|
||||
{ id: "operMngCdText", title: "운영관리형태", mergeCell: true, widthPercent: 6 },
|
||||
{ id: "oilqMeasMthdText", title: "유량측정방법", mergeCell: true, widthPercent: 6 },
|
||||
{ id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true, widthPercent: 7 },
|
||||
{ id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true, widthPercent: 6 },
|
||||
{ id: "chckYmd", title: "점검일", mergeCell: true, widthPercent: 5 },
|
||||
{ id: "utztnUsgCdText", title: "이용용도", widthPercent: 5 },
|
||||
{ id: "totalSplyUswtrUtztnQnt", title: "연간대체수이용량(m³)", widthPercent: 7 },
|
||||
{ id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)", widthPercent: 7 },
|
||||
{ id: "ph", title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 1, type: "number", edit: true, widthPercent: 5 },
|
||||
{ id: "trbt", title: "탁도(NTU)", upName: "useQuilty", upSequnce: 2, type: "number", edit: true, widthPercent: 4 },
|
||||
{ id: "grssClfg", title: "총대장균군수(개/mg)", upName: "useQuilty", upSequnce: 3, type: "number", edit: true, widthPercent: 5 },
|
||||
{ id: "vltnDt", title: "부과일(위반일)", upName: "feeHist", upSequnce: 1, type: "text", edit: true, widthPercent: 5 },
|
||||
{ id: "vltnMttr", title: "위반사항", upName: "feeHist", upSequnce: 2, type: "text", edit: true, widthPercent: 6 },
|
||||
{ id: "levyAmt", title: "부과금액(천원)", upName: "feeHist", upSequnce: 3, type: "text", edit: true, widthPercent: 5 },
|
||||
];
|
||||
|
||||
export const ruseHeadListExport: TableUpperProps[] = [
|
||||
|
||||
@@ -13,6 +13,11 @@ import {
|
||||
} from "../rainChkgdn/excel";
|
||||
import { codeToText, textToCode } from "@/components/lib/func/common";
|
||||
|
||||
const normalizeExcelDateInput = (value: unknown) => {
|
||||
if (value === undefined || value === null) return "";
|
||||
return String(value).replace(/[.\-\/\s]/g, "");
|
||||
};
|
||||
|
||||
export const rswtMakeExcelSample = (
|
||||
buildings: Buildingtype[],
|
||||
sidoCode: SelectDataType[],
|
||||
@@ -142,7 +147,9 @@ export const excelToRswtGuideData = (
|
||||
const rswtChkgdData: rswtChkZodType[] = excelData
|
||||
.map((item: any) => {
|
||||
if (item["점검일"] !== undefined) {
|
||||
const checkYmd = item["점검일"].replace(/\./g, "");
|
||||
const checkYmd = normalizeExcelDateInput(item["점검일"]);
|
||||
const operMngCd = textToCode(item["운영관리형태"], "rainRswtMng") ?? item["운영관리형태"];
|
||||
const utztnUsgCd = textToCode(item["이용용도"], "dmdUszCd") ?? item["이용용도"];
|
||||
|
||||
const makeGuidDetail = Array.from({ length: 12 }, (_, i) => {
|
||||
let month = `${i + 1}`;
|
||||
@@ -150,26 +157,27 @@ export const excelToRswtGuideData = (
|
||||
const rswtData = parseRawValue(item[`중수_${month}월`]);
|
||||
if (month.length < 2) month = "0" + month;
|
||||
return {
|
||||
utztnUsgCd: utztnUsgCd,
|
||||
ym: year + month,
|
||||
chckYmd: checkYmd,
|
||||
splyUswtrUtztnQnt: splyData !== "" ? splyData : 0,
|
||||
ruseFcltUtztnQnt: rswtData !== "" ? rswtData : 0,
|
||||
flg: "RST",
|
||||
};
|
||||
});
|
||||
if (checkYmd.length > 7) {
|
||||
return {
|
||||
bdstRuseFcltSn: Number(item["NO"]),
|
||||
operMngCd: textToCode(item["운영관리형태"], "rainRswtMng") ??item["운영관리형태"],
|
||||
anlOperCst: parseCommaRawValue(item["연간운영비(원/년)"]),
|
||||
prcsCpct: parseRawValue(item[`처리용량(m³)`]),
|
||||
spwtPositn: item["채수지점"],
|
||||
chckYmd: checkYmd,
|
||||
utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"],
|
||||
guideDetails: makeGuidDetail,
|
||||
rgtr: TEST_UUID,
|
||||
mdfr: TEST_UUID,
|
||||
};
|
||||
}
|
||||
return {
|
||||
bdstRuseFcltSn: Number(item["NO"]),
|
||||
flg: "RST",
|
||||
operMngCd: operMngCd,
|
||||
anlOperCst: parseCommaRawValue(item["연간운영비(원/년)"]),
|
||||
prcsCpct: parseRawValue(item[`처리용량(m³)`]),
|
||||
spwtPositn: item["채수지점"],
|
||||
chckYmd: checkYmd,
|
||||
utztnUsgCd: utztnUsgCd,
|
||||
guideDetails: makeGuidDetail,
|
||||
rgtr: TEST_UUID,
|
||||
mdfr: TEST_UUID,
|
||||
};
|
||||
}
|
||||
})
|
||||
.filter((el: any) => el !== undefined);
|
||||
@@ -186,11 +194,13 @@ export const excelToRswtPolution = (excelData: any) => {
|
||||
const rswtChkgdData: rswtChkZodType[] = excelData
|
||||
.map((item: any) => {
|
||||
if (item["점검일"] !== undefined) {
|
||||
const checkYmd = item["점검일"].replace(/\./g, "");
|
||||
let vltnDt = item["과태료 부과일(위반일)"];
|
||||
if (vltnDt !== undefined) {
|
||||
vltnDt = vltnDt.replace(/\./g, "");
|
||||
}
|
||||
const checkYmd = normalizeExcelDateInput(item["점검일"]);
|
||||
const vltnDt = normalizeExcelDateInput(item["과태료 부과일(위반일)"]);
|
||||
const operMngCd =
|
||||
textToCode(item["운영관리형태"], "rainRswtMng") ??
|
||||
item["운영관리형태"];
|
||||
const utztnUsgCd =
|
||||
textToCode(item["이용용도"], "dmdUszCd") ?? item["이용용도"];
|
||||
|
||||
const makePoluttion = Array.from({ length: 4 }, (_, i) => {
|
||||
const quarter = `${i + 1}`;
|
||||
@@ -207,6 +217,7 @@ export const excelToRswtPolution = (excelData: any) => {
|
||||
const ph = String(item[`${quarter}분기_PH`]) ;
|
||||
const clIonQnt = parseRawValue(item[`${quarter}분기_염화물`]);
|
||||
return {
|
||||
utztnUsgCd: utztnUsgCd,
|
||||
node: quarter,
|
||||
chckYmd: checkYmd,
|
||||
grssClfgUswtr: grssClfgUswtr,
|
||||
@@ -226,9 +237,10 @@ export const excelToRswtPolution = (excelData: any) => {
|
||||
|
||||
return {
|
||||
bdstRuseFcltSn: Number(item["NO"]),
|
||||
flg: "RST",
|
||||
chckYmd: checkYmd,
|
||||
utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"],
|
||||
operMngCd: item["운영관리형태"],
|
||||
utztnUsgCd: utztnUsgCd,
|
||||
operMngCd: operMngCd,
|
||||
anlOperCst: parseCommaRawValue(item["연간운영비(원/년)"]),
|
||||
prcsCpct: parseRawValue(item["처리용량(m³)"]),
|
||||
spwtPositn: item["채수지점"],
|
||||
@@ -237,7 +249,7 @@ export const excelToRswtPolution = (excelData: any) => {
|
||||
mdfr: TEST_UUID,
|
||||
rswtrDetails: [
|
||||
{
|
||||
utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"],
|
||||
utztnUsgCd: utztnUsgCd,
|
||||
vltnDt: vltnDt,
|
||||
vltnMttr: item["위반사항"],
|
||||
levyAmt: Number(item["과태료 부과금액(천원)"]) ?? 0,
|
||||
@@ -257,6 +269,7 @@ export const rswtExcelDataCheck = (
|
||||
rswtChkgdData: rswtChkZodType[],
|
||||
issues: string[]
|
||||
) => {
|
||||
// const chkMngType = { "01": "위탁", "02": "자체" };
|
||||
|
||||
rswtChkgdData.forEach((rswt: any) => {
|
||||
const defaultMessage = `*중수도 수질 [NO: ${rswt.bdstRuseFcltSn}, 점검일: ${rswt.chckYmd}, 이용용도: ${codeToText(rswt.utztnUsgCd ,"dmdUszCd")??rswt.utztnUsgCd}] 항목에서 `;
|
||||
@@ -264,6 +277,17 @@ export const rswtExcelDataCheck = (
|
||||
if (rswt.chckYmd && isInvalidDate(rswt.chckYmd)) {
|
||||
issues.push(defaultMessage + `점검일: 날짜 형식 아님 (${rswt.chckYmd})`);
|
||||
}
|
||||
// if (rswt.operMngCd?.length > 1 && !chkMngType[rswt.operMngCd]) {
|
||||
// issues.push(
|
||||
// defaultMessage +
|
||||
// `운영관리형태: 위탁 혹은 자체만 허용 (${rswt.operMngCd})`
|
||||
// );
|
||||
// }
|
||||
// if (rswt.utztnUsgCd?.length > 2 && !codeToText(rswt.utztnUsgCd, "dmdUszCd")) {
|
||||
// issues.push(
|
||||
// defaultMessage + `이용용도: 허용되지 않은 값 (${rswt.utztnUsgCd})`
|
||||
// );
|
||||
// }
|
||||
if (rswt.anlOperCst.length > 2 && isInvalidNumber(rswt.anlOperCst)) {
|
||||
|
||||
issues.push(
|
||||
@@ -327,6 +351,11 @@ export const rswtExcelDataCheck = (
|
||||
defaultMessage + `${pol.node}분기_T-N: 숫자 형식 아님 (${pol.tn})`
|
||||
);
|
||||
}
|
||||
if (pol.ph?.length > 1 && isInvalidNumber(pol.ph)) {
|
||||
issues.push(
|
||||
defaultMessage + `${pol.node}분기_PH: 숫자 형식 아님 (${pol.ph})`
|
||||
);
|
||||
}
|
||||
|
||||
if (isInvalidNumber(pol.clIonQnt)) {
|
||||
issues.push(
|
||||
|
||||
@@ -53,61 +53,63 @@ const buildingZod = z.object({
|
||||
});
|
||||
|
||||
export const rswtrPolutionsZode = z.object({
|
||||
utztnUsgCdText:z.string().nullish(),
|
||||
chkgdnDtlFk: z.string().nullish(),
|
||||
utztnUsgCd: z.string().nullish(),
|
||||
node: z.string().nullish(),
|
||||
grssClfgUswtr: z.number(),
|
||||
combResdch: z.number(),
|
||||
trbt: z.number(),
|
||||
bod: z.number(),
|
||||
smll: z.number(),
|
||||
crmty: z.number(),
|
||||
tph: z.number(),
|
||||
tn: z.number(),
|
||||
ph: z.number(),
|
||||
clIonQnt: z.number(),
|
||||
regDt: z.string().nullish(),
|
||||
rgtr: z.string().nullish(),
|
||||
mdfcnDt: z.string().nullish(),
|
||||
mdfr: z.string().nullish(),
|
||||
edit:z.boolean().nullish()
|
||||
utztnUsgCdText:z.string().nullish(), // 이용용도 코드의 화면 표시용 한글명
|
||||
chkgdnDtlFk: z.string().nullish(), // 지도점검 상세 PK와 연결되는 FK
|
||||
utztnUsgCd: z.string().nullish(), // 이용용도 코드
|
||||
node: z.string().nullish(), // 분기 구분값(1~4분기)
|
||||
grssClfgUswtr: z.number(), // 총대장균군수
|
||||
combResdch: z.number(), // 결합잔류염소
|
||||
trbt: z.number(), // 탁도
|
||||
bod: z.number(), // BOD
|
||||
smll: z.string(), // 냄새
|
||||
crmty: z.number(), // 색도
|
||||
tph: z.number(), // 총인(T-P)
|
||||
tn: z.number(), // 총질소(T-N)
|
||||
ph: z.number(), // 수소이온농도(pH)
|
||||
clIonQnt: z.number(), // 염화물
|
||||
regDt: z.string().nullish(), // 등록일시
|
||||
rgtr: z.string().nullish(), // 등록자
|
||||
mdfcnDt: z.string().nullish(), // 수정일시
|
||||
mdfr: z.string().nullish(), // 수정자
|
||||
edit:z.boolean().nullish() // 화면에서 수정 가능 여부
|
||||
});
|
||||
|
||||
export const rswtrDetailsZod = z.object({
|
||||
chkgdnDtlPk: z.string().nullish(),
|
||||
chkgdnSn: z.string().nullish(),
|
||||
utztnUsgCd: z.string(),
|
||||
vltnDt: z.string(),
|
||||
vltnMttr: z.string(),
|
||||
levyAmt: z.number(),
|
||||
regDt: z.string().nullish(),
|
||||
rgtr: z.string().nullish(),
|
||||
mdfcnDt: z.string().nullish(),
|
||||
mdfr: z.string().nullish(),
|
||||
chkgdnDtlPk: z.string().nullish(), // 지도점검 상세 PK
|
||||
chkgdnSn: z.string().nullish(), // 지도점검 일련번호
|
||||
utztnUsgCd: z.string(), // 이용용도 코드
|
||||
vltnDt: z.string(), // 위반일
|
||||
vltnMttr: z.string(), // 위반사항
|
||||
levyAmt: z.number(), // 부과금액
|
||||
regDt: z.string().nullish(), // 등록일시
|
||||
rgtr: z.string().nullish(), // 등록자
|
||||
mdfcnDt: z.string().nullish(), // 수정일시
|
||||
mdfr: z.string().nullish(), // 수정자
|
||||
})
|
||||
|
||||
// 중수도 점검 데이터를 검증하는 Zod 스키마
|
||||
export const rswtChkgdZod = z.object({
|
||||
chkgdnSn: z.number().nullish(),
|
||||
bdstRuseFcltSn: z.number().nullish(),
|
||||
chckYmd: z.string(),
|
||||
prcsCpct: z.number(),
|
||||
dtfcltCpct: z.number(),
|
||||
spwtPositn: z.string(),
|
||||
regDt: z.string().nullish(),
|
||||
rgtr: z.string().nullish(),
|
||||
mdfcnDt: z.string().nullish(),
|
||||
mdfr: z.string().nullish(),
|
||||
anlOperCst:z.number(),
|
||||
oilqMeasMthd: z.string().nullish(),
|
||||
utztnUsgCd: z.string(),
|
||||
building: buildingZod,
|
||||
guideDetails: z.array(guideDetail),
|
||||
reuseBuilding: reuseBuildingZod,
|
||||
chkgdnSn: z.number().nullish(), // 점검 일련번호
|
||||
bdstRuseFcltSn: z.number().nullish(), // 재이용시설 일련번호
|
||||
chckYmd: z.string(), // 점검일자
|
||||
prcsCpct: z.number(), // 처리용량
|
||||
dtfcltCpct: z.number(), // 빗물저류조용량
|
||||
spwtPositn: z.string(), // 채수 지점
|
||||
regDt: z.string().nullish(), // 등록일시
|
||||
rgtr: z.string().nullish(), // 등록자
|
||||
mdfcnDt: z.string().nullish(), // 수정일시
|
||||
mdfr: z.string().nullish(), // 수정자
|
||||
flg: z.string().nullable(), // 플래그
|
||||
anlOperCst: z.number(), // 연간 운영비
|
||||
oilqMeasMthd: z.string().nullish(), // 유량측정방법
|
||||
utztnUsgCd: z.string(), // 이용용도 코드
|
||||
building: buildingZod, // 건물 정보
|
||||
guideDetails: z.array(guideDetail), // 가이드 점검 상세 목록
|
||||
reuseBuilding: reuseBuildingZod, // 재이용 건물 정보
|
||||
rswtrDetails: z.array(
|
||||
rswtrDetailsZod
|
||||
),
|
||||
rswtrPollutions: z.array(rswtrPolutionsZode),
|
||||
), // 점검 위반/내역 상세 배열
|
||||
rswtrPollutions: z.array(rswtrPolutionsZode), // 수질 오염 항목 배열
|
||||
});
|
||||
|
||||
|
||||
@@ -134,117 +136,45 @@ export const rswtHeadNmExport: chHeadType[] = [
|
||||
];
|
||||
|
||||
export const rswtChkHeadListExport: TableUpperProps[] = [
|
||||
{ id: "order", title: "순번", mergeCell: true },
|
||||
{ id: "checkBox", title: "선택", mergeCell: true },
|
||||
{ id: "cityText", title: "시도" ,mergeCell: true },
|
||||
{ id: "sggText", title: "시군구",mergeCell: true },
|
||||
{ id: "bdstNm", title: "시설명" ,mergeCell: true},
|
||||
{ id: "operMngCd", title: "운영관리형태" ,mergeCell: true},
|
||||
{ id: "anlOperCst", title: "연간운영비(원/년)" ,mergeCell: true},
|
||||
{ id: "prcsCpct", title: "처리용량(m³)" ,mergeCell: true},
|
||||
{ id: "spwtPositn", title: "채수지점" ,mergeCell: true},
|
||||
{ id: "chckYmd", title: "점검일" ,mergeCell: true},
|
||||
{ id: "utztnUsgCdText", title: "이용용도" },
|
||||
{ id: "splyUswtrUtztnQnt", title: "연간대체수이용량(m³)" ,type: "number"},
|
||||
{ id: "ruseFcltUtztnQnt", title: "연간중수도이용량(m³)",type: "number"},
|
||||
|
||||
{
|
||||
id: "grssClfgUswtr",
|
||||
title: "총대장균군수(개/mg)",
|
||||
upName: "useQuilty",
|
||||
upSequnce: 1,
|
||||
type: "number"
|
||||
},
|
||||
{
|
||||
id: "combResdch",
|
||||
title: "결합잔류염소(mh/L)",
|
||||
upName: "useQuilty",
|
||||
upSequnce: 2,
|
||||
type: "number"
|
||||
},
|
||||
{ id: "trbt", title: "탁도(NTU)", upName: "useQuilty", upSequnce: 3 ,type: "number"},
|
||||
{ id: "bod", title: "BOD(mg/L)", upName: "useQuilty", upSequnce: 4 ,type: "number"},
|
||||
{ id: "smll", title: "냄새", upName: "useQuilty", upSequnce: 5 ,type: "text"},
|
||||
{ id: "crmty", title: "색도(도)", upName: "useQuilty", upSequnce: 6 ,type: "number"},
|
||||
{ id: "tn", title: "총질소(T-N)(mg/L)", upName: "useQuilty", upSequnce: 7 ,type: "number"},
|
||||
{ id: "tph", title: "총인(T-P)(mg/L)", upName: "useQuilty", upSequnce: 8 ,type: "number"},
|
||||
{ id: "ph", title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 9,type: "text" },
|
||||
{ id: "clIonQnt", title: "염화물(mg/L)", upName: "useQuilty", upSequnce: 10 ,type: "number"},
|
||||
|
||||
{
|
||||
id: "vltnDt",
|
||||
title: "부과일(위반일)",
|
||||
upName: "feeHist",
|
||||
upSequnce: 1,
|
||||
type: "text",
|
||||
edit:true
|
||||
},
|
||||
{
|
||||
id: "vltnMttr",
|
||||
title: "위반사항",
|
||||
upName: "feeHist",
|
||||
upSequnce: 2,
|
||||
type: "text",
|
||||
edit:true
|
||||
},
|
||||
{
|
||||
id: "levyAmt",
|
||||
title: "부과금액(천원)",
|
||||
upName: "feeHist",
|
||||
upSequnce: 3,
|
||||
type: "number",
|
||||
edit:true
|
||||
}];
|
||||
{ id: "order", title: "순번", mergeCell: true, widthPercent: 4 },
|
||||
{ id: "checkBox", title: "선택", mergeCell: true, widthPercent: 4 },
|
||||
{ id: "cityText", title: "시도" ,mergeCell: true, widthPercent: 7 },
|
||||
{ id: "sggText", title: "시군구",mergeCell: true, widthPercent: 5 },
|
||||
{ id: "bdstNm", title: "시설명" ,mergeCell: true, widthPercent: 10 },
|
||||
{ id: "operMngCd", title: "운영관리형태" ,mergeCell: true, widthPercent: 6 },
|
||||
{ id: "anlOperCst", title: "연간운영비(원/년)" ,mergeCell: true, widthPercent: 7 },
|
||||
{ id: "prcsCpct", title: "처리용량(m³)" ,mergeCell: true, widthPercent: 6 },
|
||||
{ id: "spwtPositn", title: "채수지점" ,mergeCell: true, widthPercent: 6 },
|
||||
{ id: "chckYmd", title: "점검일" ,mergeCell: true, widthPercent: 7 },
|
||||
{ id: "utztnUsgCdText", title: "이용용도", widthPercent: 7 },
|
||||
{ id: "splyUswtrUtztnQnt", title: "연간대체수이용량(m³)" ,type: "number", widthPercent: 5 },
|
||||
{ id: "ruseFcltUtztnQnt", title: "연간중수도이용량(m³)",type: "number", widthPercent: 5 },
|
||||
{ id: "grssClfgUswtr", title: "총대장균군수(개/mg)", upName: "useQuilty", upSequnce: 1 ,type: "number", widthPercent: 6 },
|
||||
{ id: "combResdch", title: "결합잔류염소(mh/L)", upName: "useQuilty", upSequnce: 2 ,type: "number", widthPercent: 6 },
|
||||
{ id: "trbt", title: "탁도(NTU)", upName: "useQuilty", upSequnce: 3 ,type: "number", widthPercent: 4 },
|
||||
{ id: "bod", title: "BOD\n(mg/L)", upName: "useQuilty", upSequnce: 4 ,type: "number", widthPercent: 4 },
|
||||
{ id: "smll", title: "냄새", upName: "useQuilty", upSequnce: 5 ,type: "text", widthPercent: 4 },
|
||||
{ id: "crmty", title: "색도(도)", upName: "useQuilty", upSequnce: 6 ,type: "number", widthPercent: 4 },
|
||||
{ id: "tn", title: "총질소(T-N)(mg/L)", upName: "useQuilty", upSequnce: 7 ,type: "number", widthPercent: 5 },
|
||||
{ id: "tph", title: "총인(T-P)(mg/L)", upName: "useQuilty", upSequnce: 8 ,type: "number", widthPercent: 5 },
|
||||
{ id: "ph", title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 9,type: "text", widthPercent: 5 },
|
||||
{ id: "clIonQnt", title: "염화물(mg/L)", upName: "useQuilty", upSequnce: 10 ,type: "number", widthPercent: 5 },
|
||||
{ id: "vltnDt", title: "부과일(위반일)", upName: "feeHist", upSequnce: 1, type: "text", edit:true, widthPercent: 5 },
|
||||
{ id: "vltnMttr", title: "위반사항", upName: "feeHist", upSequnce: 2, type: "text", edit:true, widthPercent: 6 },
|
||||
{ id: "levyAmt", title: "부과금액(천원)", upName: "feeHist", upSequnce: 3, type: "number", edit:true, widthPercent: 5 }];
|
||||
|
||||
|
||||
export const rswtDetailHeadListExport: TableUpperProps[] = [
|
||||
{ id: "utztnUsgCdText", title: "이용용도" },
|
||||
|
||||
{
|
||||
id: "grssClfgUswtr",
|
||||
title: "총대장균군수",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 2,
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "combResdch",
|
||||
title: "결합잔류염소",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 3,
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "trbt",
|
||||
title: "탁도",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 4,
|
||||
edit: true,
|
||||
},
|
||||
{ id: "bod", title: "BOD", upName: "detailQulity", upSequnce: 5, edit: true },
|
||||
{
|
||||
id: "smll",
|
||||
title: "냄새",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 6,
|
||||
edit: true,
|
||||
},
|
||||
{
|
||||
id: "crmty",
|
||||
title: "색도",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 7,
|
||||
edit: true,
|
||||
},
|
||||
{ id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8, edit: true },
|
||||
{ id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9, edit: true },
|
||||
{ id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10, edit: true },
|
||||
{
|
||||
id: "clIonQnt",
|
||||
title: "염화물",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 11,
|
||||
edit: true,
|
||||
},
|
||||
{ id: "utztnUsgCdText", title: "이용용도", widthPercent: 20 },
|
||||
{ id: "grssClfgUswtr", title: "총대장균군수", upName: "detailQulity", upSequnce: 2, edit: true, widthPercent: 8 },
|
||||
{ id: "combResdch", title: "결합잔류염소", upName: "detailQulity", upSequnce: 3, edit: true, widthPercent: 8 },
|
||||
{ id: "trbt", title: "탁도", upName: "detailQulity", upSequnce: 4, edit: true, widthPercent: 8 },
|
||||
{ id: "bod", title: "BOD", upName: "detailQulity", upSequnce: 5, edit: true, widthPercent: 8 },
|
||||
{ id: "smll", title: "냄새", upName: "detailQulity", upSequnce: 6, edit: true, widthPercent: 8 },
|
||||
{ id: "crmty", title: "색도", upName: "detailQulity", upSequnce: 7, edit: true, widthPercent: 8 },
|
||||
{ id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8, edit: true, widthPercent: 8 },
|
||||
{ id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9, edit: true, widthPercent: 8 },
|
||||
{ id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10, edit: true, widthPercent: 8 },
|
||||
{ id: "clIonQnt", title: "염화물", upName: "detailQulity", upSequnce: 11, edit: true, widthPercent: 8 },
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -41,19 +41,19 @@ export type rswtChkZodType = z.infer<typeof rswtChkgdZod>;
|
||||
export type rswtrChkDetailsZodType = z.infer<typeof rswtrDetailsZod>;
|
||||
export type rswtChkgdnState = {
|
||||
rswtChkgdn: {
|
||||
rswtChkHeadList: TableUpperProps[];
|
||||
rswtDetailHeadList: TableUpperProps[];
|
||||
|
||||
rswtHeadNm: chHeadType[];
|
||||
excelList: SheetParameter[];
|
||||
rswtChkRes: rswtChkZodType[];
|
||||
rswtChkPolGuide: rswtChkZodType[];
|
||||
rswtSplHeadNm:chHeadType[]
|
||||
rswtRuseHeadNm:chHeadType[]
|
||||
isInit: boolean;
|
||||
isSttn: boolean;
|
||||
isLoading:boolean;
|
||||
rswtChkCount: number;
|
||||
rswtChkHeadList: TableUpperProps[]; // 중수도 지도점검 메인 목록 헤더
|
||||
rswtDetailHeadList: TableUpperProps[]; // 중수도 지도점검 상세 목록 헤더
|
||||
|
||||
rswtHeadNm: chHeadType[]; // 메인 목록 다단 헤더명
|
||||
excelList: SheetParameter[]; // 엑셀 다운로드용 시트 데이터
|
||||
rswtChkRes: rswtChkZodType[]; // 중수도 지도점검 메인 목록 데이터
|
||||
rswtChkPolGuide: rswtChkZodType[]; // 선택한 지도점검 1건의 수질/대체수 상세 데이터
|
||||
rswtSplHeadNm:chHeadType[] // 공급량 관련 다단 헤더명
|
||||
rswtRuseHeadNm:chHeadType[] // 재이용량 관련 다단 헤더명
|
||||
isInit: boolean; // 초기 목록 조회 완료 여부
|
||||
isSttn: boolean; // 테이블 선택/상세 상태 제어 플래그
|
||||
isLoading:boolean; // 등록/업로드 등 비동기 처리 진행 여부
|
||||
rswtChkCount: number; // 메인 목록 전체 건수
|
||||
};
|
||||
};
|
||||
|
||||
@@ -242,27 +242,29 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 중수도 지도점검결과 upload
|
||||
rswtChkExceDataUpload: async (excelData: rswtChkZodType[],laeSeCd:string) => {
|
||||
const successMessage = "지도점검 등록이 완료되었습니다.";
|
||||
const failMessage = "지도점검 등록이 실패되었습니다.";
|
||||
console.log(excelData);
|
||||
try {
|
||||
set((state: rswtChkgdnType) => (
|
||||
{ rswtChkgdn: { ...state.rswtChkgdn, isLoading: true } }));
|
||||
set((state: rswtChkgdnType) => (
|
||||
{ rswtChkgdn: { ...state.rswtChkgdn, isLoading: true } }));
|
||||
const res = await postFectch("/reuseChk/reuseWater", excelData);
|
||||
if (!res.ok) {
|
||||
return failMessage;
|
||||
if (res.status === 200) {
|
||||
const currentYear = new Date().getFullYear().toString();
|
||||
const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, laeSeCd);
|
||||
set((state: rswtChkgdnState) => ({
|
||||
...state,
|
||||
rswtChkgdn: {
|
||||
...state.rswtChkgdn,
|
||||
rswtChkRes: rswtChkRes.data,
|
||||
rswtChkCount: rswtChkRes.count,
|
||||
},
|
||||
}));
|
||||
return successMessage;
|
||||
}
|
||||
const currentYear = new Date().getFullYear().toString();
|
||||
const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, laeSeCd);
|
||||
set((state: rswtChkgdnState) => ({
|
||||
...state,
|
||||
rswtChkgdn: {
|
||||
...state.rswtChkgdn,
|
||||
rswtChkRes: rswtChkRes.data,
|
||||
rswtChkCount: rswtChkRes.count,
|
||||
},
|
||||
}));
|
||||
return successMessage;
|
||||
return failMessage;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return failMessage;
|
||||
|
||||
@@ -56,57 +56,57 @@ export const splSttnHeadListExport: TableUpperProps[] = [
|
||||
{ id: "spl12", title: "12월", upName: "splWater", upSequnce: 13 },
|
||||
];
|
||||
|
||||
export const rswtDetailHeadListExport: TableUpperProps[] = [
|
||||
{ id: "utztnUsgCdText", title: "이용용도" },
|
||||
// export const rswtDetailHeadListExport: TableUpperProps[] = [
|
||||
// { id: "utztnUsgCdText", title: "이용용도" },
|
||||
|
||||
{
|
||||
id: "grssClfgUswtr",
|
||||
title: "총대장균군수",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 2,
|
||||
},
|
||||
{
|
||||
id: "combResdch",
|
||||
title: "결합잔류염소",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 3,
|
||||
},
|
||||
{
|
||||
id: "trbt",
|
||||
title: "탁도",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 4,
|
||||
},
|
||||
{
|
||||
id: "bod",
|
||||
title: "BOD",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 5,
|
||||
},
|
||||
{
|
||||
id: "smll",
|
||||
title: "냄새",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 6,
|
||||
},
|
||||
{
|
||||
id: "crmty",
|
||||
title: "색도",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 7,
|
||||
},
|
||||
{ id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8},
|
||||
{
|
||||
id: "tph",
|
||||
title: "T-P",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 9,
|
||||
},
|
||||
{ id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10 },
|
||||
{
|
||||
id: "clIonQnt",
|
||||
title: "염화물",
|
||||
upName: "detailQulity",
|
||||
upSequnce: 11,
|
||||
},
|
||||
];
|
||||
// {
|
||||
// id: "grssClfgUswtr",
|
||||
// title: "총대장균군수",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 2,
|
||||
// },
|
||||
// {
|
||||
// id: "combResdch",
|
||||
// title: "결합잔류염소",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 3,
|
||||
// },
|
||||
// {
|
||||
// id: "trbt",
|
||||
// title: "탁도",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 4,
|
||||
// },
|
||||
// {
|
||||
// id: "bod",
|
||||
// title: "BOD",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 5,
|
||||
// },
|
||||
// {
|
||||
// id: "smll",
|
||||
// title: "냄새",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 6,
|
||||
// },
|
||||
// {
|
||||
// id: "crmty",
|
||||
// title: "색도",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 7,
|
||||
// },
|
||||
// { id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8},
|
||||
// {
|
||||
// id: "tph",
|
||||
// title: "T-P",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 9,
|
||||
// },
|
||||
// { id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10 },
|
||||
// {
|
||||
// id: "clIonQnt",
|
||||
// title: "염화물",
|
||||
// upName: "detailQulity",
|
||||
// upSequnce: 11,
|
||||
// },
|
||||
// ];
|
||||
|
||||
@@ -43,16 +43,16 @@ export type rainChkSttnType = rainChkSttnState & rainChkSttnActions;
|
||||
|
||||
export const rainChkSttnStateExport: rainChkSttnState = {
|
||||
rainChkSttn: {
|
||||
rainChkRes: [],
|
||||
fcltDiv: fcltDiv,
|
||||
rainChkgdnHeadList: rainChkgdnHeadList,
|
||||
ruseHeadList: ruseHeadList,
|
||||
splHeadList: splHeadList,
|
||||
rainHeadNm: rainHeadNm,
|
||||
isInit: false,
|
||||
sttnExcelList: [],
|
||||
isSttn: false,
|
||||
rainChkCount: 1,
|
||||
rainChkRes: [], // 빗물이용시설 지도점검 현황 메인 목록 데이터
|
||||
fcltDiv: fcltDiv, // 시설 구분 RST 중수도시설, RNB 빗물이용시설
|
||||
rainChkgdnHeadList: rainChkgdnHeadList, // 메인 목록 테이블 헤더 정의
|
||||
ruseHeadList: ruseHeadList, // 연간 빗물이용량 상세 테이블 헤더 정의
|
||||
splHeadList: splHeadList, // 연간 대체수이용량 상세 테이블 헤더 정의
|
||||
rainHeadNm: rainHeadNm, // 메인 목록 다단 헤더명 정의
|
||||
isInit: false, // 현황 화면 초기 조회 완료 여부
|
||||
sttnExcelList: [], // 엑셀 다운로드용 가공 데이터
|
||||
isSttn: false, // 등록/현황 화면 구분 및 읽기 전용 제어 플래그
|
||||
rainChkCount: 1, // 메인 목록 전체 건수
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -31,16 +31,15 @@ export const rswtChkSttnHeadListExport: TableUpperProps[] = [
|
||||
];
|
||||
|
||||
export const rswtDetailSttnHeadListExport: TableUpperProps[] = [
|
||||
{ id: "utztnUsgCd", title: "이용용도" },
|
||||
|
||||
{ id: "grssClfgUswtr", title: "총대장균군수", upName: "detailQulity", upSequnce: 2 },
|
||||
{ id: "combResdch", title: "결합잔류염소", upName: "detailQulity", upSequnce: 3 },
|
||||
{ id: "trbt", title: "탁도", upName: "detailQulity", upSequnce: 4 },
|
||||
{ id: "bod", title: "BOD", upName: "detailQulity", upSequnce: 5 },
|
||||
{ id: "smll", title: "냄새", upName: "detailQulity", upSequnce: 6 },
|
||||
{ id: "crmty", title: "색도", upName: "detailQulity", upSequnce: 7 },
|
||||
{ id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8 },
|
||||
{ id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9 },
|
||||
{ id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10 },
|
||||
{ id: "clIonQnt", title: "염화물", upName: "detailQulity", upSequnce: 11 },
|
||||
{ id: "utztnUsgCd", title: "이용용도", widthPercent: 20 },
|
||||
{ id: "grssClfgUswtr", title: "총대장균군수", upName: "detailQulity", upSequnce: 2, widthPercent: 8 },
|
||||
{ id: "combResdch", title: "결합잔류염소", upName: "detailQulity", upSequnce: 3, widthPercent: 8 },
|
||||
{ id: "trbt", title: "탁도", upName: "detailQulity", upSequnce: 4, widthPercent: 8 },
|
||||
{ id: "bod", title: "BOD", upName: "detailQulity", upSequnce: 5, widthPercent: 8 },
|
||||
{ id: "smll", title: "냄새", upName: "detailQulity", upSequnce: 6, widthPercent: 8 },
|
||||
{ id: "crmty", title: "색도", upName: "detailQulity", upSequnce: 7, widthPercent: 8 },
|
||||
{ id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8, widthPercent: 8 },
|
||||
{ id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9, widthPercent: 8 },
|
||||
{ id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10, widthPercent: 8 },
|
||||
{ id: "clIonQnt", title: "염화물", upName: "detailQulity", upSequnce: 11, widthPercent: 8 },
|
||||
];
|
||||
|
||||
@@ -69,6 +69,7 @@ type pubFacActions = {
|
||||
pbnstInsert(pbnstRes: customPbnst): Promise<string>;
|
||||
fileDelete: (atflCd: string) => void;
|
||||
fileDownLoad: (atflCd: string) => void;
|
||||
fileDownLoadName: (atflCd: string, fileName: string) => void;
|
||||
pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void;
|
||||
pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void;
|
||||
pubHasuSearch: (page: string, sggOrCity: string, searchTxt: string) => void;
|
||||
@@ -297,6 +298,34 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
|
||||
throw new Error(`Error downloading file: ${error}`);
|
||||
}
|
||||
},
|
||||
// 파일다운로드(원본 파일명 지정) : 화면에 보여지는 파일명으로 저장
|
||||
fileDownLoadName: async (atflCd: string, fileName: string) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/attach-service/api/v1/atflcd/download/${atflCd}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
accept: "application/octet-stream",
|
||||
},
|
||||
}
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`오류 발생: ${response.status}`);
|
||||
}
|
||||
console.log(response);
|
||||
const blob = await response.blob();
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = blobUrl;
|
||||
a.download = fileName || "downloaded_file";
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
} catch (error) {
|
||||
console.error("Error downloading file with name:", error);
|
||||
throw new Error(`Error downloading file with name: ${error}`);
|
||||
}
|
||||
},
|
||||
//원수취수 팝업의 하수처리 시설 리스트 조회
|
||||
getFcOrgwts: async (fcltPkList: string[], size: number) => {
|
||||
const fcOrgwtsNmList = await postFectch(
|
||||
|
||||
@@ -10,6 +10,7 @@ export const sttnHeadListType = z.array(
|
||||
})
|
||||
);
|
||||
|
||||
// 빗물이용시설
|
||||
export const rainSttHeadListExport: z.infer<typeof sttnHeadListType> = [
|
||||
{ id: "cityText", title: "시도", visible: true, widthPercent: 4 },
|
||||
{ id: "sggText", title: "시군구", visible: true, widthPercent: 4 },
|
||||
@@ -41,7 +42,7 @@ export const rainSttHeadListExport: z.infer<typeof sttnHeadListType> = [
|
||||
{ id: "grntchBdstCertGrdText", title: "녹색건축물인증등급", visible: true, widthPercent: 4 },
|
||||
];
|
||||
|
||||
// id는 다확인해야함
|
||||
//
|
||||
export const rainSttNodeListExport: CommonTableProps[] = [
|
||||
{ id: "bdnstInfo", title: "건축물정보", visible: true, row: 1, rowSpan: 1, colSpan: 10, },
|
||||
{ id: "rainFcltInfo", title: "빗물이용시설정보", visible: true, row: 1, rowSpan: 1, colSpan: 7, },
|
||||
|
||||
@@ -94,6 +94,7 @@ export const rswtChkTableData = (chkData: rswtChkZodType[]) => {
|
||||
return makeRswtData;
|
||||
};
|
||||
|
||||
// 재이용시설등록 > 지도점검결과 등록 - table body
|
||||
export const chRowspanTable = (
|
||||
makeTableData: any[],
|
||||
headList: TableUpperProps[],
|
||||
@@ -152,7 +153,7 @@ export const chRowspanTable = (
|
||||
) : key === "order" ? (
|
||||
++order
|
||||
) : // value
|
||||
["anlOperCst", "dtfcltCpct", "prcsCpct"].includes(
|
||||
["anlOperCst", "dtfcltCpct", "prcsCpct"].includes( //연간운영비, 저류조용량, 처리용량
|
||||
head.id
|
||||
) ? (
|
||||
formatCommaNumber(value)
|
||||
@@ -233,7 +234,7 @@ export const chRowspanTable = (
|
||||
}}
|
||||
/>
|
||||
)
|
||||
) : ["smll", "ph"].includes(head.id) && head.type === "text" ? (
|
||||
) : ["smll"].includes(head.id) && head.type === "text" ? (
|
||||
<>-</>
|
||||
) : [
|
||||
"totalSplyUswtrUtztnQnt",
|
||||
@@ -311,6 +312,9 @@ const handleChange = (
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// 재이용실적등록 > 지도점검결과 등록 - 상세 modal의 body
|
||||
export const InputTableBody = (
|
||||
chgRes: any[] | [],
|
||||
headList: TableUpperProps[],
|
||||
@@ -336,6 +340,157 @@ export const InputTableBody = (
|
||||
const isSubTotal = data["용수명"] === "소계";
|
||||
const isTotal = data["구분"] === 0;
|
||||
|
||||
const bgClass = isTotal
|
||||
? "bg-[#d5e1eb] font-bold"
|
||||
: isSubTotal
|
||||
? "bg-[#e6eef5] font-semibold"
|
||||
: "";
|
||||
|
||||
return (
|
||||
<TableRow key={dataIndex + "row"}>
|
||||
{headList.map((head, headIndex) => {
|
||||
//냄새면 계산 못하게 - 로 수정
|
||||
// if (["smll"].includes(head.id)) {
|
||||
// return (
|
||||
// <TableCell
|
||||
// key={head.id + headIndex}
|
||||
// className={`w-36 ${bgClass} text-center !text-xl`}
|
||||
// >
|
||||
// <span>-</span>
|
||||
// </TableCell>
|
||||
// );
|
||||
// }
|
||||
const isTextColumn = head.id === "구분" || head.id === "utztnUsgCdText";
|
||||
const textAlignClass = isTextColumn
|
||||
? "text-center"
|
||||
: "text-right";
|
||||
|
||||
// 총합계 행이면 "구분"에서 colSpan=2로 병합
|
||||
if ( (data["구분"] === 0 || data["용수명"] === 0) && head.id === "구분" ) {
|
||||
return (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
colSpan={2}
|
||||
className="font-bold text-center bg-[#d5e1eb]"
|
||||
>
|
||||
총합계
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
// 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음
|
||||
if ( (data["구분"] === 0 || data["용수명"] === 0) && head.id === "용수명" ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 총합계 행의 나머지 셀에도 색상 적용
|
||||
if (data["구분"] === 0 || data["용수명"] === 0) {
|
||||
return (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
className="bg-[#d5e1eb] font-bold text-right"
|
||||
>
|
||||
{Number(data[head.id])
|
||||
? formatCommaNumber(data[head.id as keyof any])
|
||||
: (data[head.id as keyof any] ?? "")}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
// mergeCell 처리
|
||||
if (head.mergeCell) {
|
||||
const rowSpan = getRowSpan(chgRes, head.id, dataIndex);
|
||||
if (rowSpan === 0) return null;
|
||||
return (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
rowSpan={rowSpan}
|
||||
className={`w-36 align-middle text-center whitespace-nowrap ${bgClass}`}
|
||||
>
|
||||
{Number(data[head.id])
|
||||
? formatCommaNumber(data[head.id as keyof any])
|
||||
: (data[head.id as keyof any] ?? "")}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
// 기본 셀
|
||||
// return head.edit === true && data.edit !== false ? (
|
||||
return isEditable && head.edit === true && data.edit !== false ? (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
className={`w-36 ${bgClass}`}
|
||||
>
|
||||
<Input
|
||||
// className={`${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} !text-xl h-10 w-full`}
|
||||
className={`${textAlignClass} !text-xl h-10 w-full`}
|
||||
onChange={(e) =>
|
||||
handleCommaNumberChange(e, (val) =>
|
||||
handleChange(
|
||||
dataIndex,
|
||||
head.id,
|
||||
String(val),
|
||||
setInputData
|
||||
)
|
||||
)
|
||||
}
|
||||
value={formatCommaNumber(data[head.id as keyof any]) ?? ""}
|
||||
maxLength={numSize}
|
||||
/>
|
||||
</TableCell>
|
||||
) : (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
className={`w-36 ${bgClass}`}
|
||||
>
|
||||
<div className={`${textAlignClass} !text-xl w-full h-10`}>
|
||||
{Number(data[head.id])
|
||||
? formatCommaNumber(data[head.id as keyof any])
|
||||
: (data[head.id as keyof any] ?? "")}
|
||||
</div>
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
{chgRes.length === 0 && (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={headList.length}
|
||||
className="h-24 text-center text-gray-500"
|
||||
>
|
||||
조회된 결과가 없습니다.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// 재이용실적등록 > 하수재이용실적등록 목록 body - 하수처리수재이용 실적(m³) 등록결과
|
||||
export const pbnstTableBody = (
|
||||
chgRes: any[] | [],
|
||||
headList: TableUpperProps[],
|
||||
setInputData: (data: any[]) => void,
|
||||
isEditable: boolean = true
|
||||
) => {
|
||||
// mergeCell 처리용
|
||||
const getRowSpan = (data: any[], key: string, rowIndex: number) => {
|
||||
if (rowIndex > 0 && data[rowIndex][key] === data[rowIndex - 1][key]) {
|
||||
return 0; // 이전과 같으면 셀을 그리지 않음
|
||||
}
|
||||
let span = 1;
|
||||
for (let i = rowIndex + 1; i < data.length; i++) {
|
||||
if (data[i][key] === data[rowIndex][key]) span++;
|
||||
else break;
|
||||
}
|
||||
return span;
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{chgRes.map((data, dataIndex) => {
|
||||
// 소계/총합계 행 판별
|
||||
const isSubTotal = data["용수명"] === "소계";
|
||||
const isTotal = data["구분"] === 0;
|
||||
|
||||
const bgClass = isTotal
|
||||
? "bg-[#d5e1eb] font-bold"
|
||||
: isSubTotal
|
||||
@@ -471,5 +626,4 @@ export const InputTableBody = (
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
@@ -44,7 +44,7 @@ const diagramFileTypes = ".pdf,.jpg,.jpeg,.png,.bmp";
|
||||
* - with-layout 적용
|
||||
* - 하수처리시설에 하수재이용 시설 시설 정보를 등록한다.
|
||||
* - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다
|
||||
* indexMng: 시설정보
|
||||
* indexMng: 재이용시설정보
|
||||
* indexBiz: 차수별 정보
|
||||
* 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다.
|
||||
* */
|
||||
@@ -61,7 +61,7 @@ export function PbnstMngForm({
|
||||
setIndexMng: (index: number) => void;
|
||||
readonly: boolean;
|
||||
}) {
|
||||
const { code, pbnst, fileDelete, fileDownLoad } = useWrStore(
|
||||
const { code, pbnst, fileDelete, fileDownLoadName } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null);
|
||||
@@ -150,10 +150,10 @@ export function PbnstMngForm({
|
||||
} else {
|
||||
fileList?.forEach((item, index) => {
|
||||
const idx = files?.indexOf(item.file);
|
||||
if (idx < 0) {
|
||||
setReFiles.splice(index);
|
||||
fileDelete(item.atflCd as string);
|
||||
}
|
||||
if (idx < 0) {
|
||||
setReFiles.splice(index, 1);
|
||||
fileDelete(item.atflCd as string);
|
||||
}
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
@@ -183,7 +183,7 @@ export function PbnstMngForm({
|
||||
useEffect(() => {
|
||||
setRelationFiles([]);
|
||||
setPlanFiles([]);
|
||||
console.log("indexMng ", indexMng);
|
||||
// console.log("indexMng ", indexMng);
|
||||
|
||||
const currentItem = form.getValues(`items.${indexMng}`);
|
||||
const defaultFiles = currentItem?.fcFiles || [];
|
||||
@@ -443,7 +443,7 @@ export function PbnstMngForm({
|
||||
<span
|
||||
key={index + "plan"}
|
||||
className="text-2xl block cursor-pointer text-blue-600 hover:underline"
|
||||
onClick={() => fileDownLoad(item.atflCd)}
|
||||
onClick={() => fileDownLoadName(item.atflCd, item.file.name)}
|
||||
>
|
||||
{item.file.name}
|
||||
</span>
|
||||
@@ -462,11 +462,12 @@ export function PbnstMngForm({
|
||||
}}
|
||||
fileTypes={diagramFileTypes}
|
||||
onFileClick={(index) => {
|
||||
fileDownLoad(
|
||||
relationfiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
)?.atflCd as string
|
||||
const target = relationfiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
);
|
||||
if (target?.atflCd) {
|
||||
fileDownLoadName(target.atflCd, target.file.name);
|
||||
}
|
||||
}}
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
@@ -481,7 +482,7 @@ export function PbnstMngForm({
|
||||
<span
|
||||
key={index + "plan"}
|
||||
className="text-2xl block cursor-pointer text-blue-600 hover:underline"
|
||||
onClick={() => fileDownLoad(item.atflCd)}
|
||||
onClick={() => fileDownLoadName(item.atflCd, item.file.name)}
|
||||
>
|
||||
{item.file.name}
|
||||
</span>
|
||||
@@ -500,11 +501,12 @@ export function PbnstMngForm({
|
||||
}}
|
||||
fileTypes={diagramFileTypes}
|
||||
onFileClick={(index) => {
|
||||
fileDownLoad(
|
||||
planFiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
)?.atflCd as string
|
||||
const target = planFiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
);
|
||||
if (target?.atflCd) {
|
||||
fileDownLoadName(target.atflCd, target.file.name);
|
||||
}
|
||||
}}
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* map 시설물 layer > 하수처리시설 modal
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { pbnMapTableSize } from "@/app/store/map/pbnstMap";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* map 시설물 layer > 온배수시설 modal
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { htdfMapSize } from "@/app/store/map/htdflMap";
|
||||
import { rainMapSize } from "@/app/store/map/rainMap";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* map 시설물 layer > 빗물이용시설 modal
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { rainMapSize } from "@/app/store/map/rainMap";
|
||||
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* map 시설물 layer > 중수도시설 modal
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { rainMapSize } from "@/app/store/map/rainMap";
|
||||
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* map 시설물 layer > 하수재이용시설 modal
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { ruseMapSize } from "@/app/store/map/ruseMap";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 지도점검 결과등록 엑셀 업로드 모달
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { type rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
|
||||
import { excelToRainChkData } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel";
|
||||
@@ -8,7 +11,6 @@ import {
|
||||
excelToRswtPolution,
|
||||
rswtExcelDataCheck,
|
||||
} from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel";
|
||||
import { showConfirmToast } from "@/components/lib/func/common";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
import {
|
||||
filePicked,
|
||||
@@ -61,6 +63,8 @@ export default function ChkgdExcel({
|
||||
};
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const selectedFile = e.target.files?.[0];
|
||||
setExcelData(undefined);
|
||||
setExcelRswtData(undefined);
|
||||
if (selectedFile) {
|
||||
setFile(selectedFile);
|
||||
}
|
||||
@@ -105,12 +109,15 @@ export default function ChkgdExcel({
|
||||
);
|
||||
if (excelData.message) {
|
||||
alert(excelData.message);
|
||||
setExcelData(undefined);
|
||||
}
|
||||
if (excelData.issues && excelData.issues.length > 0) {
|
||||
excelData.issues.some((err, index) => {
|
||||
showConfirmToast(err);
|
||||
// showConfirmToast(err);
|
||||
alert(err);
|
||||
return index === 4; // true 반환 시 반복 종료
|
||||
});
|
||||
setExcelData(undefined);
|
||||
clearFile();
|
||||
} else {
|
||||
setExcelData(excelData.rainChkgdData);
|
||||
@@ -123,6 +130,7 @@ export default function ChkgdExcel({
|
||||
setRswtChkLoading(true);
|
||||
filePickedArray(file, 0)
|
||||
.then((res) => {
|
||||
setExcelRswtData(undefined);
|
||||
if (res && res?.length > 1) {
|
||||
const guideData = excelToRswtGuideData(
|
||||
res[0],
|
||||
@@ -167,16 +175,24 @@ export default function ChkgdExcel({
|
||||
|
||||
if (issues && issues.length > 0) {
|
||||
issues.some((err, index) => {
|
||||
showConfirmToast(err);
|
||||
return index === 6; // true 반환 시 반복 종료
|
||||
// showConfirmToast(err);
|
||||
alert(err);
|
||||
return index === 4; // true 반환 시 반복 종료
|
||||
});
|
||||
console.log(issues.join("\n"));
|
||||
setExcelRswtData(undefined);
|
||||
clearFile();
|
||||
} else {
|
||||
setExcelRswtData(listTotalData);
|
||||
}
|
||||
} else {
|
||||
alert("중수도 엑셀은 2개 시트가 필요합니다. 양식을 확인해주세요.");
|
||||
setExcelRswtData(undefined);
|
||||
clearFile();
|
||||
}
|
||||
})
|
||||
.finally(() => setRswtChkLoading(false));
|
||||
console.log("업로드파일 점검 완료");
|
||||
}
|
||||
}
|
||||
}, [file]);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 지도점검 상세조회/상세수정용 모달
|
||||
*/
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { TableUpperProps } from "@/app/store/common/type/header";
|
||||
import type { splRuseWaterType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
|
||||
@@ -11,10 +14,10 @@ import React, { useEffect, useState } from "react";
|
||||
import type { z } from "zod";
|
||||
|
||||
export default function ChkgdModal({
|
||||
type,
|
||||
obj,
|
||||
setIsModal,
|
||||
readonly,
|
||||
type, // 시설 구분값. "RNB"이면 빗물, 그 외는 중수도 상세 모달로 처리
|
||||
obj, // 목록에서 선택한 1건의 상세 데이터. 가이드/수질/과태료 정보 렌더링과 저장에 사용
|
||||
setIsModal, // 모달 열림 상태를 제어하는 함수. 저장 완료 시 false로 닫는다
|
||||
readonly, // 편집 가능 여부. true면 입력 가능, false면 조회 전용으로 렌더링
|
||||
}: {
|
||||
type: string;
|
||||
obj: any;
|
||||
@@ -57,7 +60,7 @@ export default function ChkgdModal({
|
||||
combResdch: 0,
|
||||
trbt: 0,
|
||||
bod: 0,
|
||||
smll: 0,
|
||||
smll: '-',
|
||||
crmty: 0,
|
||||
tph: 0,
|
||||
tn: 0,
|
||||
@@ -69,7 +72,7 @@ export default function ChkgdModal({
|
||||
useEffect(() => {
|
||||
if (rainChkSttn.isSttn) {
|
||||
setHeadList({
|
||||
splHeadList: rainChkSttn.splHeadList,
|
||||
splHeadList: rainChkSttn.splHeadList, // 연간 대체수이용량 헤더 정의
|
||||
ruseHeadList: rainChkSttn.ruseHeadList,
|
||||
rswtDetailHeadList:
|
||||
type === "RNB" ? [] : rswtChkSttn.rswtDetailSttnHeadList,
|
||||
@@ -82,9 +85,12 @@ export default function ChkgdModal({
|
||||
});
|
||||
}
|
||||
}, [
|
||||
type,
|
||||
rainChkSttn.isSttn,
|
||||
rainChkgdn.splHeadList,
|
||||
rainChkgdn.ruseHeadList,
|
||||
rainChkSttn.splHeadList,
|
||||
rainChkSttn.ruseHeadList,
|
||||
rswtChkgdn.rswtDetailHeadList,
|
||||
rswtChkSttn.rswtDetailSttnHeadList,
|
||||
]);
|
||||
@@ -156,12 +162,13 @@ export default function ChkgdModal({
|
||||
if (onlyData.length === 0) return;
|
||||
const total = initStats();
|
||||
|
||||
// 분기별 원본 수질 데이터를 모두 더해 평균 계산의 분모/분자를 만든다.
|
||||
onlyData.forEach((item) => {
|
||||
total.grssClfgUswtr += item.grssClfgUswtr;
|
||||
total.combResdch += item.combResdch;
|
||||
total.trbt += item.trbt;
|
||||
total.bod += item.bod;
|
||||
total.smll += item.smll;
|
||||
// 냄새(smll)는 수치 평균 대상이 아니라 누적하지 않는다.
|
||||
total.crmty += item.crmty;
|
||||
total.tph += item.tph;
|
||||
total.tn += item.tn;
|
||||
@@ -169,6 +176,7 @@ export default function ChkgdModal({
|
||||
total.clIonQnt += item.clIonQnt;
|
||||
});
|
||||
|
||||
// 누적 합계를 항목 개수로 나눠 화면에 표시할 평균 행을 만든다.
|
||||
const average = {
|
||||
utztnUsgCdText: "평균",
|
||||
edit: false,
|
||||
@@ -176,7 +184,7 @@ export default function ChkgdModal({
|
||||
combResdch: (total.combResdch / onlyData.length).toFixed(1),
|
||||
trbt: (total.trbt / onlyData.length).toFixed(1),
|
||||
bod: (total.bod / onlyData.length).toFixed(1),
|
||||
smll: (total.smll / onlyData.length).toFixed(1),
|
||||
smll: '-',
|
||||
crmty: (total.crmty / onlyData.length).toFixed(1),
|
||||
tph: (total.tph / onlyData.length).toFixed(1),
|
||||
tn: (total.tn / onlyData.length).toFixed(1),
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 재이용실적등록> 하수재이용 실적등록 파일등록 modal
|
||||
*/
|
||||
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
|
||||
import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList";
|
||||
import type {
|
||||
@@ -17,8 +20,9 @@ import { Button, Input } from "@common/components/ui";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
// import toast from "react-hot-toast";
|
||||
import type { z } from "zod";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
|
||||
export default function PbnPrfExcelModal({
|
||||
data,
|
||||
@@ -29,6 +33,7 @@ export default function PbnPrfExcelModal({
|
||||
setIsExcelOPen: (open: boolean) => void;
|
||||
setModalExcelData: (excelData: PrfType) => void;
|
||||
}) {
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [excelData, setExcelData] = useState<PrfType[]>();
|
||||
const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({
|
||||
@@ -65,7 +70,8 @@ export default function PbnPrfExcelModal({
|
||||
if (file) {
|
||||
const isFile = file;
|
||||
if (form.getValues("ym").length < 1) {
|
||||
toast.error("파일업로드 이전에 등록년도를 작성해주세요 ");
|
||||
// toast.error("파일업로드 이전에 등록년도를 작성해주세요 ");
|
||||
alert("파일업로드 이전에 등록년도를 작성해주세요 ");
|
||||
setFile(null);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import { Button, Input } from "@common/components/ui";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
// import toast from "react-hot-toast";
|
||||
import type { z } from "zod";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
|
||||
export default function CoRegExcel({
|
||||
isModal,
|
||||
@@ -18,6 +19,7 @@ export default function CoRegExcel({
|
||||
isModal: (open: boolean) => void;
|
||||
}) {
|
||||
const { confirm } = useConfirm();
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const { ldrmnt, loadingOpen } = useWrStore((state) => state);
|
||||
const { isLoading } = ldrmnt;
|
||||
const form = useForm<z.infer<typeof coRegExcel>>({
|
||||
@@ -76,11 +78,12 @@ export default function CoRegExcel({
|
||||
await ldrmntRegData(array);
|
||||
isModal(false);
|
||||
loadingOpen(false);
|
||||
toast.success(`잠재수요처 등록이 요청되었습니다.`);
|
||||
} catch (e) {
|
||||
// toast.success(`잠재수요처 등록이 요청되었습니다.`);
|
||||
alert("잠재수요처 등록이 요청되었습니다.");
|
||||
} catch (e: any) {
|
||||
console.log(e);
|
||||
loadingOpen(false);
|
||||
alert(e);
|
||||
// alert(e.message);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
@@ -90,7 +93,8 @@ export default function CoRegExcel({
|
||||
});
|
||||
} else {
|
||||
loadingOpen(false);
|
||||
toast.error(`엑셀 파일을 선택해 주세요.`);
|
||||
// toast.error(`엑셀 파일을 선택해 주세요.`);
|
||||
alert("엑셀 파일을 선택해 주세요.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
} from "@common/business_components";
|
||||
import { Button, Input, Label } from "@common/components";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
// import toast from "react-hot-toast";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
|
||||
export type objSearchType = {
|
||||
sgg: string | number;
|
||||
@@ -47,7 +48,7 @@ export function BdstReg<T extends MoType>({
|
||||
const { code, bdst, auth, findBdst } = useWrStore((state) => {
|
||||
return state;
|
||||
});
|
||||
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const { laeSeCd } = auth;
|
||||
|
||||
const [bdstTable, setBdstTable] = useState<BdstTypeMap[T][]>();
|
||||
@@ -73,7 +74,8 @@ export function BdstReg<T extends MoType>({
|
||||
|
||||
findBdst(String(data), searchTxt || "", moType);
|
||||
}else{
|
||||
toast.error("시도 또는 시군구를 선택하여 주십시오.");
|
||||
// toast.error("시도 또는 시군구를 선택하여 주십시오.");
|
||||
alert("시도 또는 시군구를 선택하여 주십시오.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 재이용시설등록 > 하수재이용시설등록 - 취수하수처리장 추가 modal
|
||||
*/
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type {
|
||||
@@ -12,7 +15,8 @@ import { Button } from "@common/business_components/ui/table/lib/button";
|
||||
import { Input } from "@common/components/ui";
|
||||
import { ArrowLeft, ArrowRight } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
// import toast from "react-hot-toast";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
|
||||
export default function FcOrgwtsRegModal({
|
||||
onRightSet,
|
||||
@@ -23,6 +27,7 @@ export default function FcOrgwtsRegModal({
|
||||
closeModal?: (val: boolean) => void;
|
||||
initTableData?: any[];
|
||||
}) {
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const { code, pbnst, getSwtrmtFcltNm, searchFclts } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
@@ -53,7 +58,8 @@ export default function FcOrgwtsRegModal({
|
||||
closeModal?.(false)
|
||||
}
|
||||
else {
|
||||
toast.error("취수하수처리장 목록을 선택해주세요.")
|
||||
// toast.error("취수하수처리장 목록을 선택해주세요.");
|
||||
alert("취수하수처리장 목록을 선택해주세요.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
type fcBizType,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { formH1Class } from "@/components/lib/class/comClass";
|
||||
import { InputTableBody } from "@/components/lib/func/TableData";
|
||||
import { pbnstTableBody } from "@/components/lib/func/TableData";
|
||||
import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
|
||||
import { ScrollArea, Title, UiTable } from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
@@ -341,7 +341,7 @@ export function PbnstSttnModal({ data, titleVisible,isMap}: { data: customPbnst;
|
||||
{headMakeprfmnc(pbnstPrfmncSttn.monthSttnHeadList, [])}
|
||||
</TableHeader>
|
||||
<TableBody key={prfmnc.pageKey + 'pageKey'}>
|
||||
{InputTableBody(prfData[ruseTab as keyof typeof prfData] || [], pbnstPrfmncSttn.monthSttnHeadList, setPrfData as any)}
|
||||
{pbnstTableBody(prfData[ruseTab as keyof typeof prfData] || [], pbnstPrfmncSttn.monthSttnHeadList, setPrfData as any)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{/* </ScrollArea> */}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 재이용실적등록 > 지도점검결과등록 - 연간대체수이용량, 연간중수도이용량 click시 상세 model의 table body
|
||||
*/
|
||||
"use client";
|
||||
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
|
||||
import type { TableUpperProps } from "@/app/store/common/type/header";
|
||||
@@ -41,7 +44,17 @@ export function GuideDetailsTable({
|
||||
return (
|
||||
<>
|
||||
<div className={`card !m-[1.2rem] !p-0r `}>
|
||||
<Table variant="secondary">
|
||||
<Table variant="secondary" className="table-fixed">
|
||||
<colgroup>
|
||||
{headList
|
||||
.filter((head) => head.visible !== false)
|
||||
.map((head) => (
|
||||
<col
|
||||
key={head.id}
|
||||
style={{ width: head.widthPercent ? `${head.widthPercent}%` : undefined }}
|
||||
/>
|
||||
))}
|
||||
</colgroup>
|
||||
<TableHeader className="font-bold">{headMakeprfmnc(headList, upheadList)}</TableHeader>
|
||||
<TableBody >
|
||||
{InputTableBody(inputData ?? [], headList, setInputData, readonly)}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 재이용실적등록 > 지도점검결과 등록 - 중수도 table 목록
|
||||
*/
|
||||
"use client";
|
||||
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
|
||||
import { useWrStore } from "@/app/store";
|
||||
@@ -152,11 +155,7 @@ export default function RswtChkgdTable({
|
||||
.map((head) => (
|
||||
<col
|
||||
key={head.id}
|
||||
style={{
|
||||
width: head.widthPercent
|
||||
? `${head.widthPercent}%`
|
||||
: undefined,
|
||||
}}
|
||||
style={{ width: head.widthPercent ? `${head.widthPercent}%` : undefined, }}
|
||||
/>
|
||||
))}
|
||||
</colgroup>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { CloudUpload, Paperclip } from "lucide-react";
|
||||
import { FileInput, FileUploader, FileUploaderContent, FileUploaderItem } from "./lib/file_upload";
|
||||
|
||||
const dropZoneConfig = {
|
||||
maxFiles: 5,
|
||||
maxSize: 1024 * 1024 * 100,
|
||||
@@ -9,14 +10,19 @@ const dropZoneConfig = {
|
||||
|
||||
|
||||
interface FileUploadProps {
|
||||
files: File[]; // 파일 배열
|
||||
setFiles: (files: File[] | null) => void; // 파일 배열 세터
|
||||
fileTypes?: string; // 옵션 (파일 확장자 문자열)
|
||||
onFileClick?:(index:number)=> void;
|
||||
maxFiles?: number; // 파일 클릭 핸들러
|
||||
|
||||
files: File[]; // 화면에 표시할 현재 파일 목록
|
||||
setFiles: (files: File[] | null) => void; // 추가/삭제 후 변경된 파일 목록을 부모에 전달
|
||||
fileTypes?: string; // 허용할 확장자 문자열(ex: ".pdf,.jpg")
|
||||
onFileClick?:(index:number)=> void; // 파일명 영역 클릭 시 현재 목록 기준 index 전달
|
||||
maxFiles?: number; // 업로드 가능한 최대 파일 수
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 공통 파일 업로드 UI
|
||||
* - 실제 파일 상태는 부모가 관리하고, 이 컴포넌트는 목록 표시/추가/삭제 이벤트만 위임한다.
|
||||
* - 삭제 아이콘 클릭 시 FileUploader 내부에서 index 기준으로 파일을 제외한 배열을 만든 뒤 setFiles로 전달한다.
|
||||
*/
|
||||
export const FileUpload =
|
||||
({ files, setFiles, fileTypes ,onFileClick, maxFiles}: FileUploadProps) => {
|
||||
if(maxFiles){
|
||||
@@ -51,6 +57,7 @@ export const FileUpload =
|
||||
{files&&
|
||||
files.length > 0 &&
|
||||
files.map((file:File, i:number) => (
|
||||
// i는 현재 files 배열 순번이며, 삭제/클릭 이벤트에서 같은 순번값을 사용한다.
|
||||
<FileUploaderItem key={i} index={i} onFileClick={onFileClick }>
|
||||
<Paperclip className="h-4 w-4 stroke-current" />
|
||||
<span className="w-72 truncate">{file.name}</span>
|
||||
@@ -59,4 +66,4 @@ export const FileUpload =
|
||||
</FileUploaderContent>
|
||||
</FileUploader>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ type FileUploaderContextType = {
|
||||
|
||||
const FileUploaderContext = createContext<FileUploaderContextType | null>(null);
|
||||
|
||||
// FileUploader 하위 컴포넌트들이 공통 상태와 핸들러를 사용할 수 있도록 context를 노출한다.
|
||||
export const useFileUpload = () => {
|
||||
const context = useContext(FileUploaderContext);
|
||||
if (!context) {
|
||||
@@ -54,7 +55,10 @@ type FileUploaderProps = {
|
||||
};
|
||||
|
||||
/**
|
||||
* File upload Docs: {@link: https://localhost:3000/docs/file-upload}
|
||||
* 파일 업로드의 공통 동작을 담당하는 컨테이너 컴포넌트
|
||||
* - 현재 파일 목록(value)을 기준으로 drag & drop / 선택 / 삭제를 처리한다.
|
||||
* - 실제 파일 상태는 부모가 관리하며, 변경 결과는 onValueChange로만 전달한다.
|
||||
* - FileInput, FileUploaderContent, FileUploaderItem은 이 context를 통해 같은 상태를 공유한다.
|
||||
*/
|
||||
|
||||
export const FileUploader = forwardRef<
|
||||
@@ -80,7 +84,7 @@ export const FileUploader = forwardRef<
|
||||
const [isLOF, setIsLOF] = useState(false);
|
||||
const [activeIndex, setActiveIndex] = useState(-1);
|
||||
|
||||
// MIME 타입 매핑 함수 추가
|
||||
// ".pdf,.jpg" 형태의 확장자 문자열을 react-dropzone accept 객체로 변환한다.
|
||||
const getAcceptObject = (fileTypes?: string): Record<string, string[]> => {
|
||||
if (!fileTypes) {
|
||||
return { "image/*": [".jpg", ".jpeg", ".png", ".gif"] };
|
||||
@@ -131,6 +135,7 @@ export const FileUploader = forwardRef<
|
||||
const reSelectAll = maxFiles === 1 ? true : reSelect;
|
||||
const direction: DirectionOptions = dir === "rtl" ? "rtl" : "ltr";
|
||||
|
||||
// 현재 value 배열에서 index 위치 파일만 제외한 새 배열을 부모로 전달한다.
|
||||
const removeFileFromSet = useCallback(
|
||||
(i: number) => {
|
||||
if (!value) return;
|
||||
@@ -140,6 +145,7 @@ export const FileUploader = forwardRef<
|
||||
[value, onValueChange],
|
||||
);
|
||||
|
||||
// 키보드로 파일 목록 탐색 및 삭제를 지원한다.
|
||||
const handleKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
@@ -196,6 +202,7 @@ export const FileUploader = forwardRef<
|
||||
[value, activeIndex, removeFileFromSet],
|
||||
);
|
||||
|
||||
// 드롭/선택된 파일을 현재 목록과 합쳐서 부모 상태로 반영한다.
|
||||
const onDrop = useCallback(
|
||||
(acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
|
||||
const files = acceptedFiles;
|
||||
@@ -238,6 +245,7 @@ export const FileUploader = forwardRef<
|
||||
[reSelectAll, value],
|
||||
);
|
||||
|
||||
// 최대 파일 수에 도달하면 입력 영역을 비활성화한다.
|
||||
useEffect(() => {
|
||||
if (!value) return;
|
||||
if (value.length === maxFiles) {
|
||||
@@ -247,6 +255,7 @@ export const FileUploader = forwardRef<
|
||||
setIsLOF(false);
|
||||
}, [value, maxFiles]);
|
||||
|
||||
// react-dropzone에 넘길 최종 옵션 구성
|
||||
const opts = dropzoneOptions
|
||||
? { ...dropzoneOptions, accept: getAcceptObject(acceptName) }
|
||||
: { accept, maxFiles, maxSize, multiple };
|
||||
@@ -311,7 +320,7 @@ export const FileUploaderContent = forwardRef<
|
||||
{...props}
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"w-full flex rounded-xl gap-1",
|
||||
"w-full flex rounded-xl gap-0",
|
||||
orientation === "horizontal" ? "flex-raw flex-wrap" : "flex-col",
|
||||
className,
|
||||
)}
|
||||
@@ -335,26 +344,31 @@ export const FileUploaderItem = forwardRef<
|
||||
ref={ref}
|
||||
className={cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-6 p-1 justify-between cursor-pointer relative w-full",
|
||||
"h-9 justify-between cursor-pointer relative w-full",
|
||||
className,
|
||||
isSelected ? "bg-muted" : "",
|
||||
)}
|
||||
{...props}
|
||||
|
||||
>
|
||||
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden "
|
||||
<div className="font-medium leading-normal tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden "
|
||||
onClick={() =>{onFileClick?.(index)
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"absolute",
|
||||
"!w-1/5 z-50",
|
||||
direction === "rtl" ? "top-1 left-1" : "top-1 right-1",
|
||||
direction === "rtl"
|
||||
? "left-1 top-1/2 -translate-y-1/2"
|
||||
: "right-1 top-1/2 -translate-y-1/2",
|
||||
|
||||
)}
|
||||
onClick={() =>{
|
||||
onClick={(e) =>{
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
removeFileFromSet(index)}}
|
||||
>
|
||||
<span className="sr-only">remove item {index}</span>
|
||||
|
||||
Reference in New Issue
Block a user