Merge commit 'e3ff0d5e9633446e53b17f9c14840837eb52a805' into iipbs/wr/excel
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import type { TableTripleProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import { excelDownload, tableData } from "@/components/lib/func/commom";
|
||||
import HeadChModal from "@/components/ui/modal/headChModal/headChModal";
|
||||
import {
|
||||
ContentsDiv,
|
||||
@@ -20,7 +20,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { headMakeTriple } from "./TableHead";
|
||||
|
||||
export default function RainSttn() {
|
||||
const { code, sttnCommon, excelRainSttn,excelExportAction, rainSttnSearch } =
|
||||
const { code, sttnCommon, excelExportAction, rainSttnSearch } =
|
||||
useWrStore((state) => state);
|
||||
const { rainRes } = sttnCommon;
|
||||
|
||||
@@ -66,21 +66,14 @@ export default function RainSttn() {
|
||||
useEffect(() => {
|
||||
if(sttnCommon.excelList.length>0){
|
||||
if (sttnCommon.excelList.length === 0) return;
|
||||
fetch('/sample_rainy.xlsx', {})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText)
|
||||
}
|
||||
// 받은 파일 바인너리 처리
|
||||
const blobRet = await response.arrayBuffer()
|
||||
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
|
||||
const ret =await filePickedBlob(blobRet, sttnCommon.excelList )
|
||||
console.log('ret', ret);
|
||||
})
|
||||
excelDownload(sttnCommon.excelList , '빗물재이용시설 현황','sample_rainSttn_test.xlsx')
|
||||
}
|
||||
|
||||
|
||||
}, [sttnCommon.excelList]);
|
||||
|
||||
const excelClick = useCallback((returnType:ReturnType) => {
|
||||
|
||||
let con
|
||||
if (returnType.sigunValue != '0') {
|
||||
con = returnType.sigunValue
|
||||
@@ -114,7 +107,6 @@ export default function RainSttn() {
|
||||
}
|
||||
leftChildren={undefined}
|
||||
queryClick={function (returnType: ReturnType): void {
|
||||
// page: string, total: string, con: string
|
||||
// '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}'
|
||||
let con
|
||||
if (returnType.sigunValue != '0') {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
type rainChkZodType,
|
||||
} from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { excelDownload } from "@/components/lib/func/commom";
|
||||
import ChkgdExcel from "@/components/ui/modal/chkgdExcel/chkgdExcel";
|
||||
import ChkgdModal from "@/components/ui/modal/chkgdModal/chkgdModal";
|
||||
import RainChkgdTable from "@/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable";
|
||||
@@ -53,19 +54,7 @@ export default function Page() {
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
console.log("rainChkgdn.excelList", rainChkgdn.excelList);
|
||||
if (rainChkgdn.excelList.length === 0) return;
|
||||
fetch('/sample_rainy.xlsx', {})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText)
|
||||
}
|
||||
// 받은 파일 바인너리 처리
|
||||
const blobRet = await response.arrayBuffer()
|
||||
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
|
||||
const ret =await filePickedBlob(blobRet, rainChkgdn.excelList )
|
||||
console.log('ret', ret);
|
||||
})
|
||||
excelDownload(rainChkgdn.excelList);
|
||||
}, [rainChkgdn.excelList]);
|
||||
|
||||
const excelClick= useCallback(()=>{
|
||||
|
||||
@@ -288,7 +288,7 @@ export type rainChkgdnState = {
|
||||
splHeadList: TableUpperProps[];
|
||||
rswtDetailHeadList: TableUpperProps[];
|
||||
isInit: boolean;
|
||||
excelList:ExcelExportType[] | JSON[]
|
||||
excelList:JSON[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -101,6 +101,10 @@ export type TableUpperProps = {
|
||||
type?: string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export type TableTripleProps = {
|
||||
id: string;
|
||||
title: string;
|
||||
|
||||
@@ -24,20 +24,13 @@ export type ExcelSttnRainType={
|
||||
},
|
||||
"저류조용량": string,
|
||||
},
|
||||
"3.시설운영및 이용정보"?:{
|
||||
"운영관리코드": string,
|
||||
"연간빗물운영량": string
|
||||
},
|
||||
|
||||
"3.인센티브 정보":{
|
||||
"설치비지원":{
|
||||
"설치지원비용여부": string,
|
||||
"설치지원비용": string,
|
||||
},
|
||||
"요금감면"?:{
|
||||
"감면여부": string,
|
||||
"감면근거": string,
|
||||
"감면금액": string,
|
||||
},
|
||||
|
||||
"녹색건축물인증여부":{
|
||||
"녹색건축물인증여부": string,
|
||||
"녹색건축물인증년도": string,
|
||||
@@ -47,7 +40,7 @@ export type ExcelSttnRainType={
|
||||
}
|
||||
}
|
||||
|
||||
const excelSttnParsing = (data: customRainBdst[]): ExcelSttnRainType[] => {
|
||||
export const excelSttnParsing = (data: customRainBdst[]): ExcelSttnRainType[] => {
|
||||
const excelExportData: ExcelSttnRainType[] = []
|
||||
data.forEach((item) => {
|
||||
excelExportData.push(
|
||||
@@ -89,8 +82,85 @@ const excelSttnParsing = (data: customRainBdst[]): ExcelSttnRainType[] => {
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
console.log(excelExportData)
|
||||
// excelItem = {} as ExcelSttnRainType
|
||||
// excelItem["1.건축물정보"]["행정구역"]["시도"] = item.sidoNm
|
||||
// excelItem["1.건축물정보"]["행정구역"]["시군구"] = item.sggNm
|
||||
return excelExportData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export type ExcelSttnRainTypeFlat = {
|
||||
행정구역: string;
|
||||
건축물명: string;
|
||||
주소: string;
|
||||
건축물용도코드: string;
|
||||
최초건축허가일: string;
|
||||
건축면적: string;
|
||||
법적의무대상: string;
|
||||
설치완료일시: string;
|
||||
|
||||
설치비용: string;
|
||||
집수면: string;
|
||||
여과등처리시설: string;
|
||||
저류조용량: string;
|
||||
|
||||
운영관리코드?: string;
|
||||
연간빗물운영량?: string;
|
||||
|
||||
설치지원비용여부: string;
|
||||
설치지원비용: string;
|
||||
|
||||
녹색건축물인증여부: string;
|
||||
};
|
||||
|
||||
|
||||
export const excelSttnParsingJson = (data: customRainBdst[]): ExcelSttnRainTypeFlat[] => {
|
||||
const excelExportData: ExcelSttnRainTypeFlat[] = [];
|
||||
|
||||
data.forEach((item) => {
|
||||
excelExportData.push({
|
||||
// 1.건축물정보
|
||||
"행정구역": JSON.stringify({
|
||||
시도: String(item.ctpvCd),
|
||||
시군구: String(item.sggCd)
|
||||
}),
|
||||
"건축물명": item.bdstNm ?? "",
|
||||
"주소": item.daddr ?? "",
|
||||
"건축물용도코드": String(item.bdstInfoPk ?? ""),
|
||||
"최초건축허가일": String(item.frstArchPrmsnDt ?? ""),
|
||||
"건축면적": String(item.archArea ?? ""),
|
||||
"법적의무대상": String(item.reuseBuilding?.[0]?.lawTrgtYn ?? ""),
|
||||
"설치완료일시": String(item.reuseBuilding?.[0]?.instlCmptnDt ?? ""),
|
||||
|
||||
// 2.빗물이용시설정보
|
||||
"설치비용": String(item.reuseBuilding?.[0]?.instlCst ?? ""),
|
||||
"집수면": JSON.stringify({
|
||||
집수지점종류: item.reuseBuilding?.[0]?.rainyObj?.pntfColKnd ?? "",
|
||||
집수지점면적: String(item.reuseBuilding?.[0]?.rainyObj?.pntfColArea ?? "")
|
||||
}),
|
||||
"여과등처리시설": JSON.stringify({
|
||||
여과처리시설유무: String(item.reuseBuilding?.[0]?.rainyObj?.filtrTrtmfctYn ?? ""),
|
||||
여과처리시설용량: String(item.reuseBuilding?.[0]?.rainyObj?.filtrTrtmfctCpct ?? ""),
|
||||
여과처리시설처리공정: String(item.reuseBuilding?.[0]?.rainyObj?.filtrTrtmfctPrs ?? "")
|
||||
}),
|
||||
"저류조용량": String(item.reuseBuilding?.[0]?.rainyObj?.dtfcltCpct ?? ""),
|
||||
|
||||
// 3.인센티브 정보
|
||||
"설치지원비용여부": String(item.reuseBuilding?.[0]?.instlCstSprtYn ?? ""),
|
||||
"설치지원비용": String(item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""),
|
||||
|
||||
"녹색건축물인증여부": JSON.stringify({
|
||||
녹색건축물인증여부: String(item.reuseBuilding?.[0]?.grntchBdstCertYn ?? ""),
|
||||
녹색건축물인증년도: String(item.reuseBuilding?.[0]?.grntchBdstCertYr ?? ""),
|
||||
녹색건축물인증번호: String(item.reuseBuilding?.[0]?.grntchBdstCertNo ?? ""),
|
||||
녹색건축물인증등급: String(item.reuseBuilding?.[0]?.grntchBdstCertGrd ?? "")
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
return excelExportData;
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
type TableTripleProps,
|
||||
type TableUpperProps,
|
||||
} from "../../fcltReg/rainReg";
|
||||
import type { ExcelSttnRainType } from "./excel";
|
||||
import { excelSttnParsing, excelSttnParsingJson, type ExcelSttnRainType, type FlatExcelSttnRainType } from "./excel";
|
||||
import { fetchType, getFetch } from "@/components/lib/api";
|
||||
|
||||
const pbnSttHeadNm: chHeadType[] = [
|
||||
@@ -316,7 +316,6 @@ export type sttnState = {
|
||||
type sttnActions = {
|
||||
rainSttnSearch: (page: string, total: string, con: string) => void;
|
||||
chSttnHead: (checkList: string[], type: string) => void;
|
||||
excelRainSttn:(data:JSON[] ) => void
|
||||
};
|
||||
|
||||
export type sttnType = sttnState & sttnActions;
|
||||
@@ -342,12 +341,14 @@ export const sttnActionsExport: (set: any) => sttnActions = (set: any) => {
|
||||
`/reuseFc/rainyInfoList/${page}/${total}/${con}`
|
||||
);
|
||||
if(Number(total) > 9000){
|
||||
//const rainExcel= excelSttnParsing(rainRes)
|
||||
const rainExcel= excelSttnParsing(rainRes)
|
||||
set((state: sttnState) => {
|
||||
return {
|
||||
...state,
|
||||
sttnCommon: {
|
||||
...state.sttnCommon,
|
||||
excelList: rainRes,
|
||||
excelList: rainExcel,
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -367,21 +368,6 @@ export const sttnActionsExport: (set: any) => sttnActions = (set: any) => {
|
||||
console.log("error", erTxt);
|
||||
}
|
||||
},
|
||||
excelRainSttn: async (data: JSON[]) => {
|
||||
//TODO: 엑셀 데이터 array 생성해서 return 필요. ExcelSttnRainType[]으로 생성해서 던져주면 됨.
|
||||
|
||||
|
||||
set((state: sttnState) => {
|
||||
return {
|
||||
...state,
|
||||
sttnCommon: {
|
||||
...state.sttnCommon,
|
||||
rainRes: rainRes,
|
||||
isInit: false,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
chSttnHead: async (checkList: string[], type: string) => {
|
||||
const headList =
|
||||
type === "pbn"
|
||||
@@ -423,3 +409,5 @@ export const sttnActionsExport: (set: any) => sttnActions = (set: any) => {
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { Checkbox, Input, TableCell, TableRow } from "@common/components/ui";
|
||||
|
||||
export const rightTableData = (rainChk: rainChkZodType[]) => {
|
||||
// 1. chkgdnFk + utztnUsgCd 기준 누계 정보 만들기
|
||||
const maketotal = rainChk.map((item: any) => {
|
||||
const selectTotal = item.guideDetails.reduce((acc: any, cur: any) => {
|
||||
const code = cur.utztnUsgCd;
|
||||
const fk = cur.chkgdnFk;
|
||||
|
||||
const key = `${fk}_${code}`;
|
||||
acc[key] = acc[key] || {
|
||||
totalSplyUswtrUtztnQnt: 0,
|
||||
totalRuseFcltUtztnQnt: 0,
|
||||
};
|
||||
|
||||
acc[key].totalSplyUswtrUtztnQnt += cur.splyUswtrUtztnQnt;
|
||||
acc[key].totalRuseFcltUtztnQnt += cur.ruseFcltUtztnQnt;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return selectTotal; // 모든 키: `${chkgdnFk}_${utztnUsgCd}` 형태
|
||||
});
|
||||
|
||||
// 2. 누계 정보들을 하나의 객체로 합치기 (평탄화)
|
||||
const flatTotalMap = Object.assign({}, ...maketotal);
|
||||
|
||||
// 3. rainyDetails에 누계 정보 주입
|
||||
|
||||
const updatedRainyDetails: any[] = [];
|
||||
rainChk.forEach((rd: any) => {
|
||||
const details = rd.rainyDetails.forEach((rainyItem: any) => {
|
||||
const key = `${rainyItem.chkgdnFk}_${rainyItem.utztnUsgCd}`;
|
||||
const totals = flatTotalMap[key] || {
|
||||
totalSplyUswtrUtztnQnt: 0,
|
||||
totalRuseFcltUtztnQnt: 0,
|
||||
};
|
||||
|
||||
updatedRainyDetails.push({
|
||||
...rd,
|
||||
...rd.building,
|
||||
...rainyItem,
|
||||
...totals,
|
||||
rowspan: rd.rainyDetails?.length,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return updatedRainyDetails;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const chRowspanTable = (
|
||||
makeTableData: any[],
|
||||
headList: TableUpperProps[],
|
||||
handleChange: (
|
||||
rowIndex: number,
|
||||
field: keyof (typeof makeTableData)[0],
|
||||
value: string | number
|
||||
) => void,
|
||||
toggleSelection: (pk: number, checked: boolean) => void,
|
||||
selectedIds: number[],
|
||||
handleCellClick: (index: number, headId: string) => void
|
||||
) => {
|
||||
|
||||
|
||||
|
||||
|
||||
// rowspan된 셀 렌더링 여부 추적용
|
||||
const renderedMap = new Map<string, Set<number>>();
|
||||
return (
|
||||
<>
|
||||
{makeTableData.map((row, rowIndex) => (
|
||||
<TableRow key={rowIndex}>
|
||||
{headList.map((head) => {
|
||||
const key = head.id;
|
||||
const isMerged = head.rowSpan;
|
||||
const value = row[key];
|
||||
|
||||
// 병합 대상이면 중복 렌더링 여부 판단
|
||||
if (isMerged) {
|
||||
const renderedSet = renderedMap.get(key) ?? new Set<number>();
|
||||
if (renderedSet.has(rowIndex)) return null; // 이미 렌더링된 셀은 skip
|
||||
|
||||
const rowspan = row.rowspan ?? 1;
|
||||
for (let i = 0; i < rowspan; i++) {
|
||||
renderedSet.add(rowIndex + i);
|
||||
}
|
||||
renderedMap.set(key, renderedSet);
|
||||
|
||||
return (
|
||||
<TableCell
|
||||
key={key}
|
||||
rowSpan={rowspan}
|
||||
className="align-middle text-center whitespace-nowrap"
|
||||
>
|
||||
{key === "order" ? (
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(row.chkgdnPk)}
|
||||
onCheckedChange={(checked) =>
|
||||
toggleSelection(row.chkgdnPk, checked === true)
|
||||
}
|
||||
></Checkbox>
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
|
||||
// 기본 셀
|
||||
return (
|
||||
<TableCell
|
||||
key={key}
|
||||
className="text-center whitespace-nowrap"
|
||||
onClick={() => handleCellClick(rowIndex, head.id)}
|
||||
>
|
||||
{key === "totalSplyUswtrUtztnQnt" ||
|
||||
key === "totalRuseFcltUtztnQnt" ||
|
||||
key === "utztnUsgCd" ? (
|
||||
`${value}`
|
||||
) : (
|
||||
<Input
|
||||
className={`${head.type === "number" ? "text-right" : "text-center"} text-3xl`}
|
||||
type={head.type}
|
||||
onChange={(e) => {
|
||||
handleChange(rowIndex, head.id, e.target.value);
|
||||
}}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { comCodeState, } from "@/app/store/common/code";
|
||||
import type { SelectDataType } from "@common/business_components/ui";
|
||||
import { filePickedBlob, type SelectDataType } from "@common/business_components/ui";
|
||||
|
||||
|
||||
|
||||
@@ -47,4 +47,20 @@ export const getCity = (val: string, sggCd: SelectDataType[]) => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const excelDownload =(excelList: JSON[], fileNm:string ,sampleFile:string ) =>{
|
||||
console.log("excelList", excelList);
|
||||
if (excelList.length === 0) return;
|
||||
fetch(`/${sampleFile}`, {})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText)
|
||||
}
|
||||
// 받은 파일 바인너리 처리
|
||||
const blobRet = await response.arrayBuffer()
|
||||
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
|
||||
const ret =await filePickedBlob(blobRet, excelList,fileNm )
|
||||
|
||||
})
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
"use client";
|
||||
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/page";
|
||||
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type {
|
||||
rainChkZodType,
|
||||
splRuseWaterType,
|
||||
} from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
@@ -30,7 +29,6 @@ export function GuideDetailsTable({
|
||||
const { code, rainChkgdn } = useWrStore((state) => state);
|
||||
const [guidData, setGuidData] = useState<splRuseWaterType[]>();
|
||||
|
||||
const nodeList = headMakeprfmnc(headList, rainChkgdn?.rainHeadNm);
|
||||
|
||||
const handleChange = (
|
||||
rowIndex: number,
|
||||
@@ -89,7 +87,7 @@ export function GuideDetailsTable({
|
||||
<>
|
||||
<div className={`card !m-[1.2rem] !p-0r `}>
|
||||
<Table variant="secondary">
|
||||
<TableHeader className="font-bold">{nodeList}</TableHeader>
|
||||
<TableHeader className="font-bold">{headMakeprfmnc(headList, rainChkgdn?.rainHeadNm)}</TableHeader>
|
||||
<TableBody >
|
||||
{tableBody(guidData ?? [])}
|
||||
</TableBody>
|
||||
|
||||
@@ -1,167 +1,20 @@
|
||||
"use client";
|
||||
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/page";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import { UiModal } from "@common/business_components/ui";
|
||||
import {
|
||||
Checkbox,
|
||||
Input,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
import ChkgdModal from "../../../modal/chkgdModal/chkgdModal";
|
||||
|
||||
export const totalData = (
|
||||
makeTableData: any[],
|
||||
headList: TableUpperProps[],
|
||||
handleChange: (
|
||||
rowIndex: number,
|
||||
field: keyof (typeof makeTableData)[0],
|
||||
value: string | number
|
||||
) => void,
|
||||
toggleSelection: (pk: number, checked: boolean) => void,
|
||||
selectedIds: number[],
|
||||
handleCellClick: (index: number, headId: string) => void
|
||||
) => {
|
||||
const mergeKeys = [
|
||||
"order",
|
||||
"cityText",
|
||||
"sggText",
|
||||
"bdstNm",
|
||||
"operMngCd",
|
||||
"flowCheck",
|
||||
"yearFee",
|
||||
"rainDtnbaOpct",
|
||||
"chckYmd",
|
||||
];
|
||||
|
||||
// rowspan된 셀 렌더링 여부 추적용
|
||||
const renderedMap = new Map<string, Set<number>>();
|
||||
return (
|
||||
<>
|
||||
{makeTableData.map((row, rowIndex) => (
|
||||
<TableRow key={rowIndex}>
|
||||
{headList.map((head) => {
|
||||
const key = head.id;
|
||||
const isMerged = head.rowSpan;
|
||||
const value = row[key];
|
||||
|
||||
// 병합 대상이면 중복 렌더링 여부 판단
|
||||
if (isMerged) {
|
||||
const renderedSet = renderedMap.get(key) ?? new Set<number>();
|
||||
if (renderedSet.has(rowIndex)) return null; // 이미 렌더링된 셀은 skip
|
||||
|
||||
const rowspan = row.rowspan ?? 1;
|
||||
for (let i = 0; i < rowspan; i++) {
|
||||
renderedSet.add(rowIndex + i);
|
||||
}
|
||||
renderedMap.set(key, renderedSet);
|
||||
|
||||
return (
|
||||
<TableCell
|
||||
key={key}
|
||||
rowSpan={rowspan}
|
||||
className="align-middle text-center whitespace-nowrap"
|
||||
>
|
||||
{key === "order" ? (
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(row.chkgdnPk)}
|
||||
onCheckedChange={(checked) =>
|
||||
toggleSelection(row.chkgdnPk, checked === true)
|
||||
}
|
||||
></Checkbox>
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
|
||||
// 기본 셀
|
||||
return (
|
||||
<TableCell
|
||||
key={key}
|
||||
className="text-center whitespace-nowrap"
|
||||
onClick={() => handleCellClick(rowIndex, head.id)}
|
||||
>
|
||||
{key === "totalSplyUswtrUtztnQnt" ||
|
||||
key === "totalRuseFcltUtztnQnt" ||
|
||||
key === "utztnUsgCd" ? (
|
||||
`${value}`
|
||||
) : (
|
||||
<Input
|
||||
className={`${head.type === "number" ? "text-right" : "text-center"} text-3xl`}
|
||||
type={head.type}
|
||||
onChange={(e) => {
|
||||
handleChange(rowIndex, head.id, e.target.value);
|
||||
}}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const rightTableData = (rainChk: rainChkZodType[]) => {
|
||||
// 1. chkgdnFk + utztnUsgCd 기준 누계 정보 만들기
|
||||
const maketotal = rainChk.map((item: any) => {
|
||||
const selectTotal = item.guideDetails.reduce((acc: any, cur: any) => {
|
||||
const code = cur.utztnUsgCd;
|
||||
const fk = cur.chkgdnFk;
|
||||
|
||||
const key = `${fk}_${code}`;
|
||||
acc[key] = acc[key] || {
|
||||
totalSplyUswtrUtztnQnt: 0,
|
||||
totalRuseFcltUtztnQnt: 0,
|
||||
};
|
||||
|
||||
acc[key].totalSplyUswtrUtztnQnt += cur.splyUswtrUtztnQnt;
|
||||
acc[key].totalRuseFcltUtztnQnt += cur.ruseFcltUtztnQnt;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return selectTotal; // 모든 키: `${chkgdnFk}_${utztnUsgCd}` 형태
|
||||
});
|
||||
|
||||
// 2. 누계 정보들을 하나의 객체로 합치기 (평탄화)
|
||||
const flatTotalMap = Object.assign({}, ...maketotal);
|
||||
|
||||
// 3. rainyDetails에 누계 정보 주입
|
||||
|
||||
const updatedRainyDetails: any[] = [];
|
||||
rainChk.forEach((rd: any) => {
|
||||
const details = rd.rainyDetails.forEach((rainyItem: any) => {
|
||||
const key = `${rainyItem.chkgdnFk}_${rainyItem.utztnUsgCd}`;
|
||||
const totals = flatTotalMap[key] || {
|
||||
totalSplyUswtrUtztnQnt: 0,
|
||||
totalRuseFcltUtztnQnt: 0,
|
||||
};
|
||||
|
||||
updatedRainyDetails.push({
|
||||
...rd,
|
||||
...rd.building,
|
||||
...rainyItem,
|
||||
...totals,
|
||||
rowspan: rd.rainyDetails?.length,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return updatedRainyDetails;
|
||||
};
|
||||
|
||||
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
|
||||
import {
|
||||
chRowspanTable,
|
||||
rightTableData,
|
||||
} from "@/components/lib/func/TableData";
|
||||
export default function RainChkgdTable({
|
||||
detailUp,
|
||||
}: {
|
||||
@@ -172,14 +25,14 @@ export default function RainChkgdTable({
|
||||
const { rainChk } = rainChkgdn;
|
||||
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||
const [upRaintDetail, setUpRaintDetail] = useState<rainChkZodType[]>([]);
|
||||
const [isModal, setIsModal] = useState({open:false, data:{}});
|
||||
const [isModal, setIsModal] = useState({ open: false, data: {} });
|
||||
|
||||
const handleCellClick = (index: number, headId: string) => {
|
||||
if (
|
||||
headId === "totalSplyUswtrUtztnQnt" ||
|
||||
headId === "totalRuseFcltUtztnQnt"
|
||||
) {
|
||||
setIsModal({open:true, data: makeTableData[index]});
|
||||
setIsModal({ open: true, data: makeTableData[index] });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -200,10 +53,7 @@ export default function RainChkgdTable({
|
||||
);
|
||||
};
|
||||
|
||||
const nodeList = headMakeprfmnc(
|
||||
rainChkgdn?.rainChkgdnHeadList,
|
||||
rainChkgdn?.rainHeadNm
|
||||
);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const rainChg = rainChk.map((item: any) => {
|
||||
@@ -219,8 +69,6 @@ export default function RainChkgdTable({
|
||||
setMakeTableData(rightTableData(rainChg));
|
||||
}, [rainChk, code]);
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const selectedData = makeTableData.filter((item) =>
|
||||
selectedIds.includes(item.chkgdnPk)
|
||||
@@ -271,10 +119,15 @@ export default function RainChkgdTable({
|
||||
return (
|
||||
<>
|
||||
<Table variant="secondary">
|
||||
<TableHeader className="font-bold">{nodeList}</TableHeader>
|
||||
<TableHeader className="font-bold">
|
||||
{headMakeprfmnc(
|
||||
rainChkgdn?.rainChkgdnHeadList,
|
||||
rainChkgdn?.rainHeadNm
|
||||
)}
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{totalData(
|
||||
{chRowspanTable(
|
||||
makeTableData,
|
||||
rainChkgdn.rainChkgdnHeadList,
|
||||
handleChange,
|
||||
@@ -288,10 +141,10 @@ export default function RainChkgdTable({
|
||||
<UiModal
|
||||
open={isModal.open}
|
||||
onOpenChange={() => {
|
||||
setIsModal({ open:!open , data:{} });
|
||||
setIsModal({ open: !open, data: {} });
|
||||
}}
|
||||
bodyClass={"w-[80vw] max-w-none"}
|
||||
body={<ChkgdModal type={"RNB"} obj={isModal.data} />}
|
||||
body={<ChkgdModal type={"RNB"} obj={isModal.data} />}
|
||||
></UiModal>
|
||||
</>
|
||||
);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -50,7 +50,10 @@ export const filePicked=(oFile: File, headerNum:number=0):Promise<JSON | undefin
|
||||
reader.readAsBinaryString(oFile);
|
||||
});
|
||||
}
|
||||
export const filePickedBlob=(oFile: ArrayBuffer, data:JSON[], headerNum:number=0):Promise<JSON | undefined> =>{
|
||||
|
||||
|
||||
|
||||
export const filePickedBlob=(oFile: ArrayBuffer, data:JSON[],fileNm:string, headerNum:number=0):Promise<JSON | undefined> =>{
|
||||
// Create A File Reader HTML5
|
||||
return new Promise<JSON | undefined>((resolve) => {
|
||||
// Ready The Event For When A File Gets Selected
|
||||
@@ -62,14 +65,16 @@ export const filePickedBlob=(oFile: ArrayBuffer, data:JSON[], headerNum:number=0
|
||||
if(index==0){
|
||||
const sheet = wb.Sheets[sheetName];
|
||||
if (sheet) {
|
||||
XLSX.utils.sheet_add_json(sheet,data);
|
||||
//오리진 확인 test 필요
|
||||
// XLSX.utils.sheet_add_json(sheet,data ,{origin: 3} );
|
||||
XLSX.utils.sheet_add_json(sheet,data );
|
||||
jsonXls = XLSX.utils.sheet_to_json(sheet, { range: headerNum }) as unknown as JSON;
|
||||
XLSX.writeFile(wb, "test.xlsx");
|
||||
XLSX.writeFile(wb, `${fileNm}.xlsx`);
|
||||
} else {
|
||||
console.error(`Sheet "${sheetName}" is undefined.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
resolve(jsonXls);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user