Compare commits

..
144 changed files with 4054 additions and 4895 deletions
+1 -27
View File
@@ -11,8 +11,6 @@ import {
const serverApiUrl =
process.env.NEXT_PUBLIC_SERVER_API_URL ?? "http://localhost:3000";
const linkBackendApiHost = process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080";
export function middleware(req: NextRequest) {
const pathname = req.nextUrl.pathname;
const searchParams = req.nextUrl.searchParams;
@@ -54,30 +52,6 @@ export function middleware(req: NextRequest) {
});
}
if (pathname.startsWith("/api/link")) {
const requestHeaders = new Headers(req.headers);
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
// /api/link 경로를 제거하고 백엔드 API 경로로 변환
const apiPath = pathname.replace("/api/link", "");
const queryParams = searchParams.toString();
const newUrl = `${linkBackendApiHost}${apiPath}${
queryParams ? `?${queryParams}` : ""
}`;
if (token) requestHeaders.set(CLAIM_NAME, token);
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
logMessages.push(` Link API Rewritten URL: ${newUrl}`);
logMessages.push("\n--------------------------------\n");
console.log(logMessages.join("\n"));
return NextResponse.rewrite(new URL(newUrl), {
headers: requestHeaders,
});
}
if (pathname === "/") {
return NextResponse.redirect(new URL("/dashboard", req.url));
}
@@ -88,5 +62,5 @@ export function middleware(req: NextRequest) {
}
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/"],
matcher: ["/server/:path*", "/attach-service/:path*", "/"],
};
+23 -23
View File
@@ -20,7 +20,7 @@ import {
export class LinkApiService implements LinkService {
public async getLinkList(params: LinkSearchParam): Promise<LinkList> {
const response = await axios.get<LinkList>(
`/api/link/getLinkList`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`,
{ params }
);
return response.data;
@@ -28,41 +28,41 @@ export class LinkApiService implements LinkService {
public async getLinkInfo(linkSn: string): Promise<LinkInfo> {
const response = await axios.get<LinkInfo>(
`/api/link/getLinkInfo/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkInfo/${linkSn}`,
);
return response.data;
}
public async linkQuickStart(linkSn: string): Promise<string> {
const response = await axios.patch<string>(
`/api/link/linkQuickStart/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/linkQuickStart/${linkSn}`,
);
return response.data;
}
public async updateLinkInfo(data: LinkFormData): Promise<void> {
await axios.put<void>(
'/api/link/updateLinkInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkInfo`,
data,
);
}
public async insertLinkInfo(data: LinkFormData): Promise<void> {
await axios.post<void>(
'/api/link/insertLinkInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkInfo`,
data,
);
}
public async deleteLink(linkSn: string): Promise<void> {
await axios.delete<void>(
`/api/link/deleteLink/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLink/${linkSn}`,
);
}
public async getLinkLogList(params: LinkSearchParam): Promise<LinkLogList> {
const response = await axios.get<LinkLogList>(
'/api/link/selectLinkLoglist',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/selectLinkLoglist`,
{ params }
);
return response.data;
@@ -70,7 +70,7 @@ export class LinkApiService implements LinkService {
public async getLinkStatsList(params: LinkSearchParam): Promise<LinkStatsList> {
const response = await axios.get<LinkStatsList>(
'/api/link/selectLinkStats',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/selectLinkStats`,
{ params }
);
return response.data;
@@ -78,14 +78,14 @@ export class LinkApiService implements LinkService {
public async getLinkVrblList(linkSn: string): Promise<LinkVrblList> {
const response = await axios.get<LinkVrblList>(
`/api/link/getLinkVrblList/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkVrblList/${linkSn}`,
);
return response.data;
}
public async insertLinkVrbl(data: LinkVrblFormData): Promise<number> {
const response = await axios.post<number>(
'/api/link/insertLinkVrbl',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkVrbl`,
data,
);
@@ -94,7 +94,7 @@ export class LinkApiService implements LinkService {
public async deleteLinkVrbl(data: string[]): Promise<void> {
await axios.delete<void>(
'/api/link/deleteLinkVrbl',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLinkVrbl`,
{
data
}
@@ -103,35 +103,35 @@ export class LinkApiService implements LinkService {
public async getLinkVrblInfo(linkVrblSn: string): Promise<LinkVrbl> {
const response = await axios.get<LinkVrbl>(
`/api/link/getLinkVrblInfo/${linkVrblSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkVrblInfo/${linkVrblSn}`,
);
return response.data;
}
public async updateLinkVrblInfo(data: LinkVrblFormData): Promise<void> {
await axios.put<void>(
'/api/link/updateLinkVrblInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkVrblInfo`,
data,
);
}
public async getLinkTableInfo(linkSn: string): Promise<LinkTable> {
const response = await axios.get<LinkTable>(
`/api/link/getLinkTableInfo/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableInfo/${linkSn}`,
);
return response.data;
}
public async getLinkTableColList(linkSn: string): Promise<LinkTableColumnsList> {
const response = await axios.get<LinkTableColumnsList>(
`/api/link/getLinkTableColList/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColList/${linkSn}`,
);
return response.data;
}
public async getLinkTableColInfo(params: { colSn: string; tblSn:string; }): Promise<LinkTableColumns> {
const response = await axios.get<LinkTableColumns>(
'/api/link/getLinkTableColInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkTableColInfo`,
{ params }
);
return response.data;
@@ -139,14 +139,14 @@ export class LinkApiService implements LinkService {
public async insertLinkTableCol(data: LinkTableColData): Promise<void> {
await axios.post<void>(
'/api/link/insertLinkTableCol',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkTableCol`,
data
);
}
public async deleteLinkTableCol(data: string[]): Promise<void> {
await axios.delete<void>(
'/api/link/deleteLinkTableCol',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/deleteLinkTableCol`,
{
data
},
@@ -155,35 +155,35 @@ export class LinkApiService implements LinkService {
public async updateLinkTableCol(data: LinkTableColData): Promise<void> {
axios.put<void>(
'/api/link/updateLinkTableCol',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkTableCol`,
data,
);
}
public async insertLinkTableInfo(data: LinkTableFormData): Promise<void> {
await axios.post<void>(
'/api/link/insertLinkTableInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/insertLinkTableInfo`,
data
);
}
public async updateLinkTableInfo(data: LinkTableFormData): Promise<void> {
await axios.put<void>(
'/api/link/updateLinkTableInfo',
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkTableInfo`,
data
);
}
public async countLinkTblNm(tblNm: string): Promise<{count: number, tbl_sn: string}> {
const response = await axios.get<{count: number, tbl_sn: string}>(
`/api/link/countLinkTblNm/${tblNm}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/countLinkTblNm/${tblNm}`,
);
return response.data;
}
public async updateLinkResultCode(linkSn: string): Promise<void> {
await axios.patch<void>(
`/api/link/updateLinkResultCode/${linkSn}`,
`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/updateLinkResultCode/${linkSn}`,
);
}
}
@@ -118,7 +118,7 @@ function DashboardPage() {
금일 신규 가입자
{data?.memberTodayCnt
? data.memberTodayCnt.toLocaleString()
: "0"}
: "-"}
명
</p>
</div>
@@ -141,7 +141,7 @@ function DashboardPage() {
</div>
<p className="mt-1 text-2xl opacity-80">
금일 +
{data?.pstTodayCnt ? data.pstTodayCnt.toLocaleString() : "0"}
{data?.pstTodayCnt ? data.pstTodayCnt.toLocaleString() : "-"}{" "}
등록
</p>
</div>
@@ -168,7 +168,7 @@ function DashboardPage() {
전일 대비 +
{data?.accessBefDayPer
? data.accessBefDayPer.toLocaleString()
: "0"}
: "-"}
%
</p>
</div>
@@ -70,7 +70,7 @@ function LinkParamsPage() {
// Link 목록 쿼리
const query = useQuery({
queryKey: ['api/link/getLinkList', linkSearchParam],
queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam],
queryFn: () => LinkApi.getLinkList({
...linkSearchParam,
page: pagination.pageIndex,
@@ -142,10 +142,9 @@ function LinkParamsPage() {
const { mutateAsync: deleteLinkVrbl } = useMutation({
mutationFn: async (data: string[]) => await LinkApi.deleteLinkVrbl(data),
onSuccess: async () => {
await queryClient.refetchQueries({
await queryClient.invalidateQueries({
queryKey: ['linkVrblList', selectedLink.linkSn]
});
setSelectedVrblIds([]);
alert('삭제되었습니다.');
}
@@ -67,7 +67,7 @@ function LinkTablePage() {
};
const query = useQuery({
queryKey: ['/api/link/getLinkList', linkSearchParam],
queryKey: [`${process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST}/getLinkList`, linkSearchParam],
queryFn: () => LinkApi.getLinkList({
...linkSearchParam,
page: pagination.pageIndex,
@@ -1,33 +0,0 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import {
type ConnectionLogParams,
type ConnectionLogList,
type ConnectionStatisticsParams,
type ConnectionStatistics,
type ConnectionLogService,
} from "../model/connection-log-interface";
class ConnectionLogApiService implements ConnectionLogService {
async getConnectionLog(
params: ConnectionLogParams,
): Promise<ConnectionLogList> {
const response = await client.get<ConnectionLogList>(
`${ENDPOINT.CMS_SERVICE.CONNECTION_LOG}`,
{ params },
);
return response.data;
}
async getConnectionStatistics(
params: ConnectionStatisticsParams,
): Promise<ConnectionStatistics> {
const response = await client.get<ConnectionStatistics>(
`${ENDPOINT.CMS_SERVICE.CONNECTION_LOG}/stat`,
{ params },
);
return response.data;
}
}
export const ConnectionLogApi = new ConnectionLogApiService();
@@ -0,0 +1 @@
export { UserStatisticsApi } from "./user-statistics-service";
@@ -0,0 +1,138 @@
import {
type AccessLog,
type AccessLogParams,
type AccessLogService,
type PageableList,
} from "../model/user-statistics-interface";
// 목 데이터
const mockAccessLogs: AccessLog[] = [
{
no: 1,
accessTime: "2024-01-15 14:30:25",
accessIp: "192.168.1.100",
accessRegion: "서울특별시",
urlPath: "/index",
browser: "Chrome",
site: "SITE1",
accessType: "메인",
},
{
no: 2,
accessTime: "2024-01-15 14:28:15",
accessIp: "203.241.50.123",
accessRegion: "부산광역시",
urlPath: "/board/list",
browser: "Edge",
site: "SITE2",
accessType: "게시판",
},
{
no: 3,
accessTime: "2024-01-15 14:25:42",
accessIp: "175.223.45.67",
accessRegion: "대구광역시",
urlPath: "/statistics",
browser: "Safari",
site: "SITE1",
accessType: "통계",
},
{
no: 4,
accessTime: "2024-01-15 14:22:18",
accessIp: "211.252.87.45",
accessRegion: "인천광역시",
urlPath: "/contents/view",
browser: "Firefox",
site: "SITE3",
accessType: "컨텐츠",
},
{
no: 5,
accessTime: "2024-01-15 14:20:33",
accessIp: "121.254.12.89",
accessRegion: "광주광역시",
urlPath: "/search",
browser: "Chrome",
site: "SITE1",
accessType: "검색",
},
];
// 목 API 서비스
class UserStatisticsApiImpl implements AccessLogService {
async getAccessLogList(
params: AccessLogParams,
): Promise<PageableList<AccessLog>> {
// 실제 API 호출 대신 목 데이터 반환
const { page = 0, size = 10 } = params;
// 필터링 로직 (실제로는 서버에서 처리)
let filteredLogs = [...mockAccessLogs];
if (params.urlPath) {
filteredLogs = filteredLogs.filter((log) =>
log.urlPath.toLowerCase().includes(params.urlPath!.toLowerCase()),
);
}
if (params.accessIp) {
filteredLogs = filteredLogs.filter((log) =>
log.accessIp.includes(params.accessIp!),
);
}
if (params.accessRegion) {
filteredLogs = filteredLogs.filter((log) =>
log.accessRegion.includes(params.accessRegion!),
);
}
if (params.browser) {
filteredLogs = filteredLogs.filter(
(log) => log.browser.toLowerCase() === params.browser!.toLowerCase(),
);
}
if (params.siteId) {
filteredLogs = filteredLogs.filter((log) => log.site === params.siteId);
}
// 페이지네이션
const start = page * size;
const end = start + size;
const paginatedLogs = filteredLogs.slice(start, end);
// 목 응답 생성
return {
content: paginatedLogs,
pageable: {
pageNumber: page,
pageSize: size,
sort: {
empty: true,
sorted: false,
unsorted: true,
},
offset: page * size,
paged: true,
unpaged: false,
},
last: (page + 1) * size >= filteredLogs.length,
totalPages: Math.ceil(filteredLogs.length / size),
totalElements: filteredLogs.length,
size,
number: page,
sort: {
empty: true,
sorted: false,
unsorted: true,
},
first: page === 0,
numberOfElements: paginatedLogs.length,
empty: paginatedLogs.length === 0,
};
}
}
export const UserStatisticsApi = new UserStatisticsApiImpl();
@@ -1,103 +1,148 @@
import type { ChartData, ChartOptions } from "chart.js";
import { getCssVariableValue } from "@common/components";
import type { ConnectionStatistics } from "./connection-log-interface";
import { type ChartData, type ChartOptions } from "chart.js";
export const chartData = {
day: (
data: ConnectionStatistics,
): {
data: ChartData<"line">;
options: ChartOptions<"line">;
} => {
return {
data: {
labels: data.dayList.map((item) => item.dayYmd),
datasets: [
{
type: "line",
label: "접속자 수",
data: data.dayList.map((item) => item.accessCnt),
borderColor: getCssVariableValue("--chart-1"),
},
],
},
options: {
maintainAspectRatio: false,
scales: {
y: {
ticks: {
precision: 0,
},
},
},
},
};
},
site: (
data: ConnectionStatistics,
): {
data: ChartData<"bar">;
options: ChartOptions<"bar">;
} => {
return {
data: {
labels: data.siteList.map((item) => item.siteNm),
datasets: [
{
type: "bar",
label: "사이트별 접속자",
data: data.siteList.map((item) => item.accessCnt),
backgroundColor: data.siteList.map((_, index) =>
getCssVariableValue(`--chart-${(index % 5) + 1}`),
),
},
],
},
options: {
maintainAspectRatio: false,
indexAxis: "y",
scales: {
x: {
ticks: {
precision: 0,
},
},
},
plugins: {
legend: {
display: false,
},
},
},
};
},
browser: (
data: ConnectionStatistics,
): {
data: ChartData<"doughnut">;
options: ChartOptions<"doughnut">;
} => {
return {
data: {
labels: data.browserList.map((item) => item.wbsrKndNm),
datasets: [
{
type: "doughnut",
data: data.browserList.map((item) => item.accessCnt),
backgroundColor: data.browserList.map((_, index) =>
getCssVariableValue(`--chart-${(index % 5) + 1}`),
),
},
],
},
options: {
maintainAspectRatio: false,
plugins: {
legend: {
position: "bottom",
},
},
},
};
// 일별 접속 현황 차트 데이터
export const monthlyStatisticsData = {
labels: [
"1일",
"2일",
"3일",
"4일",
"5일",
"6일",
"7일",
"8일",
"9일",
"10일",
"11일",
"12일",
"13일",
"14일",
"15일",
],
datasets: [
{
type: "bar" as const,
label: "페이지뷰",
data: [
850, 1000, 750, 750, 700, 750, 780, 800, 850, 900, 1200, 1700, 2300,
2100, 2600,
],
backgroundColor: "rgba(54, 162, 235, 0.8)",
order: 2,
},
{
type: "line" as const,
label: "신규 접속자",
data: [
700, 600, 500, 550, 500, 550, 500, 550, 600, 850, 1200, 1500, 1700,
2300, 2200,
],
borderColor: "rgba(255, 99, 132, 0.8)",
borderWidth: 2,
tension: 0.4,
pointRadius: 3,
order: 0,
},
{
type: "line" as const,
label: "총 접속자",
data: [
200, 300, 400, 500, 600, 500, 550, 500, 400, 500, 350, 800, 900, 1200,
1300,
],
borderColor: "rgba(75, 192, 192, 0.8)",
borderWidth: 2,
tension: 0.4,
pointRadius: 3,
order: 1,
},
],
};
export const monthlyStatisticsOptions: ChartOptions<"bar"> = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: "top" as const,
},
tooltip: {
mode: "index" as const,
intersect: false,
},
},
};
// 사이트별 접속자 차트 데이터
export const siteVisitorsData: ChartData<"bar"> = {
labels: ["SITE1", "SITE2", "SITE3", "SITE4", "SITE5"],
datasets: [
{
label: "사이트별 접속자",
data: [2500, 2000, 1500, 1200, 800],
backgroundColor: [
"rgba(54, 162, 235, 0.8)",
"rgba(153, 102, 255, 0.8)",
"rgba(255, 99, 132, 0.8)",
"rgba(255, 159, 64, 0.8)",
"rgba(255, 205, 86, 0.8)",
],
borderWidth: 1,
},
],
};
export const siteVisitorsOptions: ChartOptions<"bar"> = {
responsive: true,
maintainAspectRatio: false,
indexAxis: "y" as const,
plugins: {
legend: {
display: false,
},
},
};
// 브라우저별 접속자 차트 데이터
export const browserStatisticsData: ChartData<"doughnut"> = {
labels: ["Chrome", "Edge", "Safari", "Firefox", "Internet Explorer"],
datasets: [
{
data: [45, 25, 15, 10, 5],
backgroundColor: [
"rgba(54, 162, 235, 0.8)",
"rgba(153, 102, 255, 0.8)",
"rgba(255, 99, 132, 0.8)",
"rgba(255, 159, 64, 0.8)",
"rgba(255, 205, 86, 0.8)",
],
borderColor: [
"rgba(54, 162, 235, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 99, 132, 1)",
"rgba(255, 159, 64, 1)",
"rgba(255, 205, 86, 1)",
],
borderWidth: 1,
},
],
};
export const browserStatisticsOptions: ChartOptions<"doughnut"> = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: "bottom" as const,
},
},
};
export const chartData = {
monthlyStatisticsData,
monthlyStatisticsOptions,
siteVisitorsData,
siteVisitorsOptions,
browserStatisticsData,
browserStatisticsOptions,
};
@@ -1,72 +0,0 @@
import type { PageableList, PageableParams } from "@/shared/model";
export interface ConnectionLogParams extends PageableParams {
keywordType?: string;
keyword?: string;
siteId?: string;
cntnIp?: string;
cntnRgn?: string;
wbsrKnd?: string;
urlPath?: string;
cntnDtStart?: string;
cntnDtEnd?: string;
}
export interface ConnectionLog {
cntnSn: number;
cntnDt: string;
cntnId: string;
cntnIp: string;
cntnRgn: string;
wbsrKnd: string;
menuCd: number;
siteId: string;
urlPath: string;
siteNm: string;
menuNm: string;
wbsrKndNm: string;
}
export interface ConnectionStatisticsParams {
keywordType?: string;
keyword?: string;
siteId?: string;
cntnIp?: string;
cntnRgn?: string;
wbsrKnd?: string;
urlPath?: string;
cntnDtStart?: string;
cntnDtEnd?: string;
}
interface DayConnectionStatistics {
dayYmd: string;
accessCnt: number;
}
interface SiteConnectionStatistics {
siteId: string;
siteNm: string;
accessCnt: number;
}
interface BrowserConnectionStatistics {
wbsrKnd: string;
wbsrKndNm: string;
accessCnt: number;
}
export interface ConnectionStatistics {
dayList: DayConnectionStatistics[];
siteList: SiteConnectionStatistics[];
browserList: BrowserConnectionStatistics[];
}
export type ConnectionLogList = PageableList<ConnectionLog>;
export interface ConnectionLogService {
getConnectionLog(params: ConnectionLogParams): Promise<ConnectionLogList>;
getConnectionStatistics(
params: ConnectionStatisticsParams,
): Promise<ConnectionStatistics>;
}
@@ -1,46 +1,39 @@
import type { ColumnDef } from "@tanstack/react-table";
import type { ConnectionLog } from "./connection-log-interface";
import dayjs from "dayjs";
import { createColumnHelper } from "@tanstack/react-table";
import { type AccessLog } from "./user-statistics-interface";
export const columns: ColumnDef<ConnectionLog>[] = [
{
const columnHelper = createColumnHelper<AccessLog>();
export const columns = [
columnHelper.accessor("no", {
header: "No",
cell: ({ row, table }) => {
const totalRows = table.getRowCount();
const currentPage = table.getState().pagination.pageIndex;
const pageSize = table.getState().pagination.pageSize;
return totalRows - (currentPage * pageSize + row.index);
},
},
{
accessorKey: "cntnDt",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("accessTime", {
header: "접속일시",
cell: ({ row }) => {
return dayjs(row.original.cntnDt).format("YYYY-MM-DD HH:mm:ss");
},
},
{
accessorKey: "cntnIp",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("accessIp", {
header: "접속IP",
},
{
accessorKey: "cntnRgn",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("accessRegion", {
header: "접속지역",
},
{
accessorKey: "urlPath",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("urlPath", {
header: "URL경로",
},
{
accessorKey: "wbsrKndNm",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("browser", {
header: "브라우저",
},
{
accessorKey: "siteNm",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("site", {
header: "사이트",
},
{
accessorKey: "menuNm",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("accessType", {
header: "메뉴명",
},
cell: (info) => info.getValue(),
}),
];
@@ -0,0 +1,56 @@
export interface AccessLog {
no: number;
accessTime: string;
accessIp: string;
accessRegion: string;
urlPath: string;
browser: string;
site: string;
accessType: string;
}
export interface AccessLogParams {
page?: number;
size?: number;
urlPath?: string;
accessIp?: string;
accessRegion?: string;
browser?: string;
accessDateStart?: string;
accessDateEnd?: string;
siteId?: string;
sort?: string;
}
export interface AccessLogService {
getAccessLogList(params: AccessLogParams): Promise<PageableList<AccessLog>>;
}
export interface PageableList<T> {
content: T[];
pageable: {
pageNumber: number;
pageSize: number;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
offset: number;
paged: boolean;
unpaged: boolean;
};
last: boolean;
totalPages: number;
totalElements: number;
size: number;
number: number;
sort: {
empty: boolean;
sorted: boolean;
unsorted: boolean;
};
first: boolean;
numberOfElements: number;
empty: boolean;
}
@@ -15,8 +15,9 @@ import {
Filler,
Legend,
Tooltip,
type ChartData,
} from "chart.js";
import { Bar, Doughnut, Line } from "react-chartjs-2";
import { Bar, Doughnut } from "react-chartjs-2";
import {
Button,
Input,
@@ -29,13 +30,11 @@ import {
} from "@common/components";
import { SiteSelect } from "@/entities/site";
import { useDataTable } from "@/shared/lib";
import { ENDPOINT } from "@/shared/config";
import { NoData } from "@/shared/ui/no-data";
import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker";
import { ConnectionLogApi } from "../api/connection-log-service";
import { UserStatisticsApi } from "../api";
import { chartData } from "../model/chart-data";
import { columns } from "../model/table-columns";
import type { ConnectionStatisticsParams } from "../model/connection-log-interface";
import { type AccessLogParams } from "../model/user-statistics-interface";
ChartJS.register(
CategoryScale,
@@ -66,31 +65,25 @@ function UserStatisticsPage() {
});
const [keywordType, setKeywordType] = useState("");
const [keyword, setKeyword] = useState("");
const [siteId, setSiteId] = useState("");
const [presetDateRange, setPresetDateRange] = useState("1W");
const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange);
const [searchParams, setSearchParams] = useState<ConnectionStatisticsParams>({
keywordType: "",
keyword: "",
siteId: "",
cntnDtStart: dayjs(defaultDateRange.from).format("YYYY-MM-DD"),
cntnDtEnd: dayjs(defaultDateRange.to).format("YYYY-MM-DD"),
const [searchParams, setSearchParams] = useState<AccessLogParams>({
urlPath: "",
accessIp: "",
accessRegion: "",
browser: "",
accessDateStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"),
accessDateEnd: dayjs().format("YYYY-MM-DD"),
sort: "accessTime,desc",
});
const query = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.CONNECTION_LOG, searchParams],
queryKey: ["user-statistics", searchParams, pagination],
queryFn: () =>
ConnectionLogApi.getConnectionLog({
...searchParams,
}),
placeholderData: keepPreviousData,
});
const { data: connectionStatisticsData } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.CONNECTION_LOG, searchParams],
queryFn: () =>
ConnectionLogApi.getConnectionStatistics({
UserStatisticsApi.getAccessLogList({
...searchParams,
page: pagination.pageIndex,
size: pagination.pageSize,
}),
placeholderData: keepPreviousData,
});
@@ -146,30 +139,54 @@ function UserStatisticsPage() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const params: ConnectionStatisticsParams = {
keywordType,
keyword,
siteId,
cntnDtStart: dateRange.from
setPagination({
...pagination,
pageIndex: 0,
});
// 검색 조건에 따라 검색 파라미터 설정
const params: AccessLogParams = {
sort: "accessTime,desc",
accessDateStart: dateRange.from
? dayjs(dateRange.from).format("YYYY-MM-DD")
: "",
cntnDtEnd: dateRange.to ? dayjs(dateRange.to).format("YYYY-MM-DD") : "",
accessDateEnd: dateRange.to
? dayjs(dateRange.to).format("YYYY-MM-DD")
: "",
};
// 검색어 타입에 따라 파라미터 설정
switch (keywordType) {
case "urlPath":
params.urlPath = keyword;
break;
case "ip":
params.accessIp = keyword;
break;
case "region":
params.accessRegion = keyword;
break;
case "browser":
params.browser = keyword;
break;
}
setSearchParams(params);
};
const handleReset = () => {
setKeywordType("");
setKeyword("");
setSiteId("");
setDateRange(defaultDateRange);
setPresetDateRange("1W");
setSearchParams({
keywordType: "",
keyword: "",
siteId: "",
cntnDtStart: dayjs(defaultDateRange.from).format("YYYY-MM-DD"),
cntnDtEnd: dayjs(defaultDateRange.to).format("YYYY-MM-DD"),
urlPath: "",
accessIp: "",
accessRegion: "",
browser: "",
accessDateStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"),
accessDateEnd: dayjs().format("YYYY-MM-DD"),
sort: "accessTime,desc",
});
};
@@ -193,11 +210,7 @@ function UserStatisticsPage() {
setDateRange={handleDateRangeChange}
/>
<Label className="ml-4 mr-2 text-label">사이트</Label>
<SiteSelect
className="w-[16rem]"
value={siteId}
onValueChange={(value) => setSiteId(value)}
/>
<SiteSelect enabledAllSite className="w-[16rem]" />
<Label className="ml-4 mr-2 text-label">검색</Label>
<Select
value={keywordType}
@@ -208,9 +221,9 @@ function UserStatisticsPage() {
</SelectTrigger>
<SelectContent>
<SelectItem value="urlPath">URL경로</SelectItem>
<SelectItem value="cntnIp">접속IP</SelectItem>
<SelectItem value="cntnRgn">접속지역</SelectItem>
<SelectItem value="wbsrKnd">브라우저</SelectItem>
<SelectItem value="ip">접속IP</SelectItem>
<SelectItem value="region">접속지역</SelectItem>
<SelectItem value="browser">브라우저</SelectItem>
</SelectContent>
</Select>
<Input
@@ -232,44 +245,45 @@ function UserStatisticsPage() {
</form>
</div>
{/* 차트 영역 */}
<div className="grid grid-cols-2">
{/* 일별 접속 현황 */}
<div className="card card-border">
<div className="card-header">
<h3 className="text-2xl font-medium">일별 접속 현황</h3>
<h3 className="text-xl font-medium">일별 접속 현황</h3>
</div>
<div className="h-96 p-4">
{connectionStatisticsData?.dayList?.length ? (
<Line {...chartData.day(connectionStatisticsData)} />
) : (
<NoData />
)}
<Bar
data={chartData.monthlyStatisticsData as ChartData<"bar">}
options={chartData.monthlyStatisticsOptions}
/>
</div>
</div>
<div className="grid grid-cols-2">
{/* 사이트별 접속자 */}
<div className="card card-border">
<div className="card-header">
<h3 className="text-2xl font-medium">사이트별 접속자</h3>
<h3 className="text-xl font-medium">사이트별 접속자</h3>
</div>
<div className="h-96 p-4">
{connectionStatisticsData?.siteList?.length ? (
<Bar {...chartData.site(connectionStatisticsData)} />
) : (
<NoData />
)}
<Bar
data={chartData.siteVisitorsData}
options={chartData.siteVisitorsOptions}
/>
</div>
</div>
{/* 브라우저별 접속자 */}
<div className="card card-border">
<div className="card-header">
<h3 className="text-2xl font-medium">브라우저별 접속자</h3>
<h3 className="text-xl font-medium">브라우저별 접속자</h3>
</div>
<div className="h-96 p-4">
{connectionStatisticsData?.browserList?.length ? (
<Doughnut {...chartData.browser(connectionStatisticsData)} />
) : (
<NoData />
)}
<Doughnut
data={chartData.browserStatisticsData}
options={chartData.browserStatisticsOptions}
/>
</div>
</div>
</div>
-1
View File
@@ -55,7 +55,6 @@ export const ENDPOINT = {
MANAGER_IP: "/cms-service/api/v1/mgrip",
APILOG: "/cms-service/api/v1/api-logs",
SITE_AUTHORITY: "/cms-service/api/v1/site-authrt",
CONNECTION_LOG: "/cms-service/api/v1/cntnlog",
},
BOARD_SERVICE: {
BBS: "/board-service/api/v1/bbs",
+1 -2
View File
@@ -25,7 +25,6 @@ function PostAction({ children, handleDelete }: PostActionProps) {
const { prompt } = useSelectPrompt(selectData);
const bbsInfo = useMenuStore((state) => state.bbsInfo);
const userInfo = useUserStore((state) => state.userInfo);
const postPageLink = `/bbs/${bbsInfo?.bbsTypeCd.toLowerCase()}/${bbsInfo?.bbsId}`;
const onDelete = async () => {
const { resolved, value } = await prompt("삭제 사유를 입력해주세요.");
@@ -65,7 +64,7 @@ function PostAction({ children, handleDelete }: PostActionProps) {
size="lg"
color="white"
type="button"
onClick={() => router.push(postPageLink)}
onClick={() => router.back()}
>
목록
</Button>
@@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter, useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
import { FormProvider, useForm, type SubmitHandler } from "react-hook-form";
import { Toaster } from "react-hot-toast";
import toast, { Toaster } from "react-hot-toast";
import * as z from "zod";
import SdmLogin from "../sdmLogin/page";
@@ -291,6 +291,7 @@ function SdmInfoInsertContent() {
open={!isLogin}
onOpenChange={(open) => {
if (!open) {
toast.dismiss();
router.push("/");
}
}}
@@ -131,7 +131,7 @@ export default function WrAboutPage() {
물재이용 필요성
</h2>
<section aria-labelledby="card2-desc" className="bg-white border border-gray-300 rounded-xl p-[60px] pt-[70px] pb-[70px] ">
<h1 id="card2-desc" className="font-NotoSansKR text-[#ED5534] text-5xl font-semibold mb-8">물 재이용, 왜 필요한가요?</h1>
<h1 id="card2-desc" className="font-NotoSansKR text-[#D63F1F] text-5xl font-semibold mb-8">물 재이용, 왜 필요한가요?</h1>
<p className="font-NotoSansKR text-2xl font-normal mb-10 leading-relaxed">
빗물, 중수, 하수처리수는 지속적으로 이용 가능한 순환자원입니다.<br />
물 재이용을 통한 효율적인 수자원 활용은 물 스트레스국가인 우리나라에서<br />가뭄대응능력 향상 및 하천수질보전을 위해 반드시 필요한 일입니다.
@@ -237,7 +237,7 @@ export default function WrAboutPage() {
하수 재이용
</h2>
<section aria-labelledby="card5-desc" className="bg-white border border-gray-300 rounded-xl p-[60px] pt-[70px] pb-[70px] ">
<h1 id="card5-desc" className="font-NotoSansKR leading-snug text-[#0099A4] text-5xl font-bold mb-6">아직 할 일이 많은 하수처리수,<br />풍족하게 재이용할 수 있어요!</h1>
<h1 id="card5-desc" className="font-NotoSansKR leading-snug text-[#00818A] text-5xl font-bold mb-6">아직 할 일이 많은 하수처리수,<br />풍족하게 재이용할 수 있어요!</h1>
<p className="font-NotoSansKR text-2xl mb-10 leading-relaxed">사용하고 버려져 공공하수처리장으로 모여든 물은<br />용도에 맞는 처리 후 재이용 할 수 있습니다.</p>
<Image
src="/img/wrAbout/img_05_1.png"
+10 -12
View File
@@ -62,9 +62,10 @@ const Map = () => {
Object.keys(item).length > 0 &&
!prev.some((f) => f.pbnstRuseFcltId === item.pbnstRuseFcltId)
);
console.log(newItems);
console.log(newItems)
return [...prev, ...newItems];
});
} catch (error) {
console.error("데이터 불러오기 실패:", error);
}
@@ -231,6 +232,14 @@ const Map = () => {
return (
<>
<SearchBar
setHasuPk={(hasuPk: any) => {
if (hasuPk) {
setSelectDataPk(hasuPk);
}
}}
onApply={onApply}
/>
<div className="bg-container">
<Gis
treeData={treeData}
@@ -248,17 +257,6 @@ const Map = () => {
isSearchModalOpen={isSearchModalOpen}
onCheckedLayersChange={onCheckedLayersChange}
imgVisble={false}
searchBar={(props: any) => (
<SearchBar
setHasuPk={(hasuPk: any) => {
if (hasuPk) {
setSelectDataPk(hasuPk);
}
}}
onApply={onApply}
{...props}
/>
)}
/>
</div>
<SelectedFcltList
+3
View File
@@ -8,6 +8,9 @@ export default function RootLayout({
}>) {
return (
<html lang="ko">
<head>
<title>물재이용 대민</title>
</head>
<body>
{children}
</body>
@@ -4,8 +4,9 @@ import type { DemandCompType } from "@common/business_components/ui/sdmInsertFor
import { Button, Input } from "@common/components";
import { zodResolver } from "@hookform/resolvers/zod";
import { sha512 } from 'js-sha512';
import { useEffect, useState, useMemo } from "react";
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm, type ControllerRenderProps } from "react-hook-form";
import toast from "react-hot-toast";
import * as z from "zod";
export function SdmLoginForm() {
@@ -15,10 +16,10 @@ export function SdmLoginForm() {
const formatBusinessNumber = (value: string) => {
// 숫자만 추출
const digitsOnly = value.replace(/\D/g, "");
// 10자리까지만 처리
const limitedDigits = digitsOnly.slice(0, 10);
// 3-2-5 형식으로 포맷팅
if (limitedDigits.length <= 3) {
return limitedDigits;
@@ -28,18 +29,18 @@ export function SdmLoginForm() {
return `${limitedDigits.slice(0, 3)}-${limitedDigits.slice(3, 5)}-${limitedDigits.slice(5)}`;
}
};
// 스키마를 useMemo로 최적화
const sdmLoginFormSchema = useMemo(() => z.object({
dmdInfoId: z.string()
.min(1, "사업자등록번호를 입력해주세요")
.regex(/^\d{10}$/, "사업자등록번호는 10자리 숫자만 입력 가능합니다"),
bznmTotNo: isBznmTotNoDisabled
bznmTotNo: isBznmTotNoDisabled
? z.string().optional()
: z.string().length(4, "종사업자등록번호는 4자리 숫자만 입력 가능합니다"),
password: z.string()
.min(1, "비밀번호를 입력해주세요")
.min(8, "비밀번호는 8자 이상 입력해주세요")
.min(8, "비밀번호는 8자 이상 입력해주세요")
.max(16, "비밀번호는 16자 이내로 입력해주세요"),
rgtr: z.string().optional(),
dmdAplyPswd: z.string().optional(),
@@ -47,7 +48,7 @@ export function SdmLoginForm() {
type FormData = z.infer<typeof sdmLoginFormSchema>;
type FieldComponent = (field: ControllerRenderProps<FormData, keyof FormData>) => JSX.Element;
const formSchema = sdmLoginFormSchema;
useEffect(() => {
@@ -72,6 +73,26 @@ export function SdmLoginForm() {
setIsBznmTotNoDisabled(checked);
};
const initPassword = () => {
toast(
(t) => (
<div className="flex flex-col items-center">
<div className="text-2xl mb-2">
관리자(031-0000-0000)에게 비밀번호 초기화 요청을 유선으로 하시기 바랍니다.
</div>
<Button size={"sm"} onClick={() => toast.dismiss(t.id)}>
확인
</Button>
</div>
),
{
id: "pwd-reset",
duration: Infinity,
position: "top-center",
}
);
}
const handleLogin = () => {
const data = form.getValues();
const passwordStr = sha512.hex(data.password)
@@ -82,61 +103,61 @@ export function SdmLoginForm() {
}
actionLogin(param as unknown as DemandCompType);
};
const formFields: Array<{
name: keyof FormData;
label: string;
component: FieldComponent | undefined;
}> = [
{
name: "dmdInfoId",
label: "사업자등록번호",
component: (field) => (
<Input
placeholder="사업자등록번호를 입력하세요"
type="text"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
value={formatBusinessNumber(field.value as string)}
onChange={(e) => {
const dmdId = e.target.value.replace(/\D/g, "").slice(0, 10);
field.onChange(dmdId);
}}
/>
)
},
{
name: "bznmTotNo",
label: BZNM_TOT_NO || "종사업자등록번호",
component: (field) => (
<FormUi
label="종사업자등록번호"
onCheckboxChange={handleCheckboxChange}
isDisabled={isBznmTotNoDisabled}
>
<Input
placeholder="여러사업장이 있을 경우 입력해주세요"
{
name: "dmdInfoId",
label: "사업자등록번호",
component: (field) => (
<Input
placeholder="사업자등록번호를 입력하세요"
type="text"
className="!mt-5 !text-xl text-gray-600"
disabled={isBznmTotNoDisabled}
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
value={formatBusinessNumber(field.value as string)}
onChange={(e) => {
const dmdId = e.target.value.replace(/\D/g, "").slice(0, 10);
field.onChange(dmdId);
}}
/>
)
},
{
name: "bznmTotNo",
label: BZNM_TOT_NO || "종사업자등록번호",
component: (field) => (
<FormUi
label="종사업자등록번호"
onCheckboxChange={handleCheckboxChange}
isDisabled={isBznmTotNoDisabled}
>
<Input
placeholder="여러사업장이 있을 경우 입력해주세요"
type="text"
className="!mt-5 !text-xl text-gray-600"
disabled={isBznmTotNoDisabled}
{...field}
/>
</FormUi>
)
},
{
name: "password",
label: "비밀번호",
component: (field) => (
<Input
placeholder="비밀번호를 입력하세요"
type="password"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
/>
</FormUi>
)
},
{
name: "password",
label: "비밀번호",
component: (field) => (
<Input
placeholder="비밀번호를 입력하세요"
type="password"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
/>
)
}
];
)
}
];
return (
<>
@@ -148,11 +169,11 @@ export function SdmLoginForm() {
control={form.control}
name={name}
render={({ field }) => (
label==='종사업자등록번호' ?
<>
label === '종사업자등록번호' ?
<>
{component && component(field)}
</>
: <FormUi label={label}>
: <FormUi label={label}>
{component && component(field)}
</FormUi>
)}
@@ -160,12 +181,15 @@ export function SdmLoginForm() {
))}
</FormProvider>
<div className="flex justify-center pt-4">
<Button
onClick={handleLogin}
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
>
로그인
</Button>
<div className="flex flex-col items-center">
<Button
onClick={handleLogin}
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
>
로그인
</Button>
<div className="text-xl mt-2 text-gray-400 cursor-pointer" onClick={initPassword}>비밀번호 초기화 요청</div>
</div>
</div>
</div>
</>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 35 KiB

@@ -16,6 +16,7 @@ export class LoginApiService implements LoginService {
public async login(payload: ILogin): Promise<void> {
try {
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
method: "POST",
body: JSON.stringify({
-1
View File
@@ -2,7 +2,6 @@ NEXT_PUBLIC_SITE_ID = FO
NEXT_PUBLIC_PORT = 11300
NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300
NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
+1 -2
View File
@@ -1,8 +1,7 @@
NEXT_PUBLIC_SITE_ID = FO
NEXT_PUBLIC_PORT = 3000
NEXT_PUBLIC_PROXY_HOST = http://localhost:3000
NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
-1
View File
@@ -15,7 +15,6 @@ NEXT_PUBLIC_SITE_ID = FO
NEXT_PUBLIC_PORT = 11300
NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300
NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
@@ -97,7 +97,10 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay;
if(flowPanel === '2'){
if(flowPanel === '1') {
const infoRnDay = (item as T & { infoRnDay: number }).infoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay>0 && infoRnDay < 3;
} else if(flowPanel === '2'){
const infoRnDay = (item as T & { infoRnDay: number }).infoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 3 && infoRnDay < 10;
} else if(flowPanel === '3'){
@@ -119,7 +122,8 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
const infoRnDay = (item as T & { infoRnDay: number }).infoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 60;
} else {
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (rainEffectDay ===1);
const infoRnDay = (item as T & { infoRnDay: number }).infoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (infoRnDay>0 || rainEffectDay ===1);
}
});
} else if(tabName.includes("_chuncheon")) {
@@ -128,8 +132,8 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
const itemDateOnly = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate());
const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && rainEffectDay==0;
const infoRnDay = (item as T & { infoRnDay: number }).infoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay==0;
});
} else {
filteredData = searchList.filter((item) => {
@@ -140,6 +144,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
return itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly;
});
}
setCopySearchList(filteredData);
setStandSearchList(filteredData);
}, [searchList, searchYear, tabName, flowPanel]);
@@ -15,6 +15,7 @@ export default function DrainageEquipment({searchYear = '', fcltyList = []}: Dra
const {
Common,
DrainageEquipment,
searchDrainageEquipment,
} = useFoStore((state) => state);
const {
@@ -34,10 +35,11 @@ export default function DrainageEquipment({searchYear = '', fcltyList = []}: Dra
useEffect(() => {
if (!isInit && tableData[0]?.bscFctCd && (tableData[0].bscFctCd !== prevFacilityCode || !hasSearched)) {
searchDrainageEquipment(searchYear, tableData[0].bscFctCd, false);
setHasSearched(true);
setPrevFacilityCode(tableData[0].bscFctCd);
}
}, [fcltyList, isInit, searchYear, tableData, hasSearched, prevFacilityCode]);
}, [fcltyList, isInit, searchDrainageEquipment, searchYear, tableData, hasSearched, prevFacilityCode]);
// 연도가 바뀌면 hasSearched를 false로 리셋
useEffect(() => {
@@ -5,7 +5,6 @@ import { ContentsDiv, UiModal, UiTable } from "@common/business_components";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
import { useEffect, useState } from "react";
import DashBoardChartModal from "./modal/page";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export type facilityInfoProps = {
searchYear?: string;
@@ -57,7 +56,7 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
PlanFclty,
OperationStatus,
searchOperationStatus,
searchPlanInfo,
searchPlanInfo
} = useFoStore((state) => state);
const [modalItem, setModalItem] = useState<{item: string, period: string, title: string, waterQlty: string} | null>(null);
@@ -78,18 +77,13 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
const {
upHeadListPlanFclty,
planFcltyList,
planYearList,
waterUsage1,
waterUsage2,
waterUsage3,
isLoadingPlanFclty
planYearList
} = PlanFclty;
// 그리드 관련
const {
upHeadListOperationStatus,
operationalStatusList,
isLoadingOperationStatus
operationalStatusList
} = OperationStatus;
const closeModal = () => {
@@ -153,27 +147,20 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
searchPlanInfo(searchYear, fcltyList[0].bscFctCd);
setHasSearched(true);
setPrevFacilityCode(fcltyList[0].bscFctCd);
}
}, [isInit, searchOperationStatus, searchYear, fcltyList, hasSearched, prevFacilityCode, searchPlanInfo]);
// waterUsage 값들이 로드된 후에 테이블 데이터 업데이트
useEffect(() => {
if (waterUsage1 !== '' && waterUsage2 !== '' && waterUsage3 !== '') {
planFcltyList.forEach((el: { [key: string]: string | number | boolean }, index) => {
if (index === 6) {
el['item'] = (Number(searchYear)-2).toString();
el['provisionalApproval'] = waterUsage3;
el['provisionalApproval'] = Number(fcltyList[0]?.fcltyCpc)* 0.6;
} else if (index === 7) {
el['item'] = (Number(searchYear)-1).toString();
el['provisionalApproval'] = waterUsage2;
el['provisionalApproval'] = Number(fcltyList[0]?.fcltyCpc)* 0.6;
} else if (index === 8) {
el['item'] = (Number(searchYear)-0).toString();
el['provisionalApproval'] = waterUsage1;
el['provisionalApproval'] = Number(fcltyList[0]?.fcltyCpc)* 0.6;
}
});
console.log('planFcltyList :', planFcltyList);
}
}, [waterUsage1, waterUsage2, waterUsage3, searchYear, planFcltyList]);
}, [isInit, searchOperationStatus, searchYear, fcltyList, hasSearched, prevFacilityCode, searchPlanInfo, planFcltyList]);
// 연도가 바뀌면 hasSearched를 false로 리셋
useEffect(() => {
setHasSearched(false);
@@ -203,7 +190,6 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
<>
<UiTable headName={""} tableData={mappedTableData} headlist={upHeadListFclty} pageSize={0} total={0} cellClick={ undefined } onPageChange={() => { } } />
<ContentsDiv>
<LoadingOverlay isLoading={isLoadingPlanFclty} />
<div className="grid grid-cols-12 gap-1">
<div className="col-span-5">
<Table variant="secondary">
@@ -225,8 +211,8 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
:(index < 5 || index > 5)&& (index!= 4) && (head.id ==='provisionalApproval'||head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour')
?<TableCell className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
:(head.id === "provisionalApproval" && index === 4)
?<TableCell colSpan={6} className="text-right border border-[var(--border)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{Math.round((Number(waterUsage1)+Number(waterUsage2)+Number(waterUsage3))/3 * 100)/100}</TableCell>
:((head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour') )
?<TableCell colSpan={6} className="text-right border border-[var(--border)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{(Number(fcltyList[0]?.fcltyCpc)* 0.6).toLocaleString('en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 })} </TableCell>
:((head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour') && index === 4)
?null
:(head.id === 'item' && index != 5)?
<TableCell className="text-center text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
@@ -239,40 +225,39 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
</div>
<div className="col-span-7 h-[600px] overflow-x-auto">
<div className="w-[200%]">
<LoadingOverlay isLoading={isLoadingOperationStatus} />
<Table variant="secondary">
<TableHeader>
{upChangeHeadListOperationStatus}
</TableHeader>
<TableBody>
{operationalStatusList.map((el: { [key: string]: string | number | boolean },index) => (
<TableRow key={index+"row"} >
{upHeadListOperationStatus.map((head) => (
(head.id === 'flowRate' && index === 0)?<TableCell rowSpan={5} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'flowRate' && index === 5)?<TableCell rowSpan={6} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'flowRate' && index === 11)?<TableCell rowSpan={2} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'groundWaterAvg'||head.id === 'groundWaterSummer'||head.id === 'groundWaterWinter')&&(index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'groundWaterAvg'||head.id === 'groundWaterSummer'||head.id === 'groundWaterWinter')&&(index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'rdi'&&index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'rdi'&&index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'rdiRain'&&index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el['rdiRain']}</TableCell>:
(head.id === 'rdiRain'&&index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}></TableCell>:
(head.id === 'waterQlty')?<TableCell className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=5 && index<=10))?<TableCell className="bg-green-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=0 && index<=4))?<TableCell className="bg-yellow-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=5 && index<=10))?<TableCell className="bg-green-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=11 && index<=12))?<TableCell className="bg-blue-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=5 && index<=10))?<TableCell className="bg-green-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
null
))}
</TableRow>
))}
</TableBody>
</Table>
<Table variant="secondary">
<TableHeader>
{upChangeHeadListOperationStatus}
</TableHeader>
<TableBody>
{operationalStatusList.map((el: { [key: string]: string | number | boolean },index) => (
<TableRow key={index+"row"} >
{upHeadListOperationStatus.map((head) => (
(head.id === 'flowRate' && index === 0)?<TableCell rowSpan={5} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'flowRate' && index === 5)?<TableCell rowSpan={6} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'flowRate' && index === 11)?<TableCell rowSpan={2} className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'groundWaterAvg'||head.id === 'groundWaterSummer'||head.id === 'groundWaterWinter')&&(index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'groundWaterAvg'||head.id === 'groundWaterSummer'||head.id === 'groundWaterWinter')&&(index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'rdi'&&index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
(head.id === 'rdi'&&index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}></TableCell>:
(head.id === 'rdiRain'&&index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el['rdiRain']}</TableCell>:
(head.id === 'rdiRain'&&index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}></TableCell>:
(head.id === 'waterQlty')?<TableCell className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=5 && index<=10))?<TableCell className="bg-green-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=0 && index<=4))?<TableCell className="bg-yellow-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=5 && index<=10))?<TableCell className="bg-green-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=11 && index<=12))?<TableCell className="bg-blue-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=5 && index<=10))?<TableCell className="bg-green-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
null
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
</div>
@@ -5,7 +5,6 @@ import { CHART_FORM, type ChartConfig, ContentsDiv, MainChart } from "@common/bu
import { Card, CardContent } from "@common/business_components/ui/chart/lib/card";
import ListDiv from "@common/business_components/ui/list_div";
import { useEffect, useState } from "react";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
type facilityInfoProps = {
searchYear?: string;
@@ -45,7 +44,6 @@ export default function DashBoardChart({searchYear = '', fcltyList = []}: facili
chart_inflTn,
chart_efflTn,
chart_inflBod,
isLoadingMainGraph,
} = MainGraph;
/**
@@ -181,7 +179,6 @@ export default function DashBoardChart({searchYear = '', fcltyList = []}: facili
return (
<>
<ContentsDiv>
<LoadingOverlay isLoading={isLoadingMainGraph} />
<ListDiv className="h-[300px]">
<Card className="h-full">
<CardContent className="h-full">
+3 -5
View File
@@ -57,7 +57,8 @@ export default function DashBoard() {
/******************선택된 데이터******************/
// 연도
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || '0');
//const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || '0');
const [searchYear, setSearchYear] = useState<string>('2023');
// 시설명
const [fcltyList, setFcltyList] = useState<{bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | ''}>({
bscFctCd: '26260PB001R',
@@ -279,11 +280,8 @@ export default function DashBoard() {
trtFrfNm: '표준활성슬러지법, MLE, MBR',
efflWqltStndrdNm: '500톤 이상(Ⅳ지역)'
});
setSearchYear(selectSearchYear[0]?.val || '0');
setSearchYear('2023');
searchFcltyList.bscFctNm = '수영';
setSidoValue('0');
setSigunValue('0');
}
const searchVal = () => {
@@ -45,7 +45,6 @@ export default function RainManageTab({searchYear = '', fcltyList = []}: facilit
}, [searchYear]);
return (
<div>
<UiTable
headName=""
tableData={rainManageList}
@@ -56,7 +55,5 @@ export default function RainManageTab({searchYear = '', fcltyList = []}: facilit
onPageChange={() => {}}
>
</UiTable>
<span className="text-2xl font-bold text-gray-500">☞ 일수에 강우영향일 포함됨</span>
</div>
)
}
@@ -5,7 +5,6 @@ import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, Selec
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import PrecipitationModal from "./modal/page";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function FacilityPrecipitation() {
const {Common
@@ -40,8 +39,7 @@ export default function FacilityPrecipitation() {
upHeadList3,
excelList,
facilityPrecipitation,
facilityPrecipitationCount,
isLoading,
facilityPrecipitationCount
} = FacilityPrecipitation;
const {
@@ -83,7 +81,8 @@ export default function FacilityPrecipitation() {
// 시설상태
const [operationValue, setOperationValue] = useState<string>("0");
// 조회기간
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
//const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYear, setSearchYear] = useState<string>("2023");
/**
* 페이지 함수
@@ -127,9 +126,9 @@ export default function FacilityPrecipitation() {
useEffect(() => {
if (!isInit) {
initializeCommonData();
searchFacilityPrecipitationList(1, 10, selectSearchYear[0]?.val || "0");
searchFacilityPrecipitationList(1, 10, searchYear || "0");
}
}, [isInit, initializeCommonData, searchFacilityPrecipitationList]);
}, [isInit, initializeCommonData, searchFacilityPrecipitationList, searchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -228,7 +227,6 @@ export default function FacilityPrecipitation() {
initClick={resetVal}
ref={ref} isAdmin={false} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"시설별 강수현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
@@ -66,11 +66,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let maxefflWqltToc = 0;
let maxEfflWqltSs = 0;
let maxinflAssctBfrWqltBod = 0;
let maxinflAssctBfrWqltTn = 0;
let maxInflAssctAftWqltBod = 0;
let maxInflAssctAftWqltTn = 0;
let maxInflAssctBfrWqltTp = 0;
let maxinflAssctBfrWqltToc = 0;
let maxinflAssctBfrWqltSs = 0;
let maxInflAssctAftWqltToc = 0;
let maxInflAssctAftWqltSs = 0;
let maxTpInflWqltBod = 0;
let maxTpInflWqltTp = 0;
@@ -83,11 +83,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let minefflWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltToc) : 0;
let minEfflWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltSs) : 0;
let mininflAssctBfrWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltBod) : 0;
let mininflAssctBfrWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTn) : 0;
let minInflAssctAftWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctAftWqltBod) : 0;
let minInflAssctAftWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctAftWqltTn) : 0;
let minInflAssctBfrWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTp) : 0;
let mininflAssctBfrWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltToc) : 0;
let mininflAssctBfrWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltSs) : 0;
let minInflAssctAftWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctAftWqltToc) : 0;
let minInflAssctAftWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctAftWqltSs) : 0;
let minTpInflWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.tpInflWqltBod) : 0;
let minTpInflWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.tpInflWqltTp) : 0;
@@ -100,11 +100,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let avgefflWqltToc = 0;
let avgEfflWqltSs = 0;
let avginflAssctBfrWqltBod = 0;
let avginflAssctBfrWqltTn = 0;
let avgInflAssctAftWqltBod = 0;
let avgInflAssctAftWqltTn = 0;
let avgInflAssctBfrWqltTp = 0;
let avginflAssctBfrWqltToc = 0;
let avginflAssctBfrWqltSs = 0;
let avgInflAssctAftWqltToc = 0;
let avgInflAssctAftWqltSs = 0;
let avgTpInflWqltBod = 0;
let avgTpInflWqltTp = 0;
@@ -118,11 +118,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
const efflWqltToc = parseNumber(item.efflWqltToc);
const efflWqltSs = parseNumber(item.efflWqltSs);
const inflAssctBfrWqltBod = parseNumber(item.inflAssctBfrWqltBod);
const inflAssctBfrWqltTn = parseNumber(item.inflAssctBfrWqltTn);
const inflAssctAftWqltBod = parseNumber(item.inflAssctAftWqltBod);
const inflAssctAftWqltTn = parseNumber(item.inflAssctAftWqltTn);
const inflAssctBfrWqltTp = parseNumber(item.inflAssctBfrWqltTp);
const inflAssctBfrWqltToc = parseNumber(item.inflAssctBfrWqltToc);
const inflAssctBfrWqltSs = parseNumber(item.inflAssctBfrWqltSs);
const inflAssctAftWqltToc = parseNumber(item.inflAssctAftWqltToc);
const inflAssctAftWqltSs = parseNumber(item.inflAssctAftWqltSs);
const tpInflWqltBod = parseNumber(item.tpInflWqltBod);
@@ -136,11 +136,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
maxefflWqltToc = Math.max(maxefflWqltToc, efflWqltToc);
maxEfflWqltSs = Math.max(maxEfflWqltSs, efflWqltSs);
maxinflAssctBfrWqltBod = Math.max(maxinflAssctBfrWqltBod, inflAssctBfrWqltBod);
maxinflAssctBfrWqltTn = Math.max(maxinflAssctBfrWqltTn, inflAssctBfrWqltTn);
maxInflAssctAftWqltBod = Math.max(maxInflAssctAftWqltBod, inflAssctAftWqltBod);
maxInflAssctAftWqltTn = Math.max(maxInflAssctAftWqltTn, inflAssctAftWqltTn);
maxInflAssctBfrWqltTp = Math.max(maxInflAssctBfrWqltTp, inflAssctBfrWqltTp);
maxinflAssctBfrWqltToc = Math.max(maxinflAssctBfrWqltToc, inflAssctBfrWqltToc);
maxinflAssctBfrWqltSs = Math.max(maxinflAssctBfrWqltSs, inflAssctBfrWqltSs);
maxInflAssctAftWqltToc = Math.max(maxInflAssctAftWqltToc, inflAssctAftWqltToc);
maxInflAssctAftWqltSs = Math.max(maxInflAssctAftWqltSs, inflAssctAftWqltSs);
maxTpInflWqltBod = Math.max(maxTpInflWqltBod, tpInflWqltBod);
maxTpInflWqltTp = Math.max(maxTpInflWqltTp, tpInflWqltTp);
@@ -153,11 +153,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
minefflWqltToc = Math.min(minefflWqltToc, efflWqltToc);
minEfflWqltSs = Math.min(minEfflWqltSs, efflWqltSs);
mininflAssctBfrWqltBod = Math.min(mininflAssctBfrWqltBod, inflAssctBfrWqltBod);
mininflAssctBfrWqltTn = Math.min(mininflAssctBfrWqltTn, inflAssctBfrWqltTn);
minInflAssctAftWqltBod = Math.min(minInflAssctAftWqltBod, inflAssctAftWqltBod);
minInflAssctAftWqltTn = Math.min(minInflAssctAftWqltTn, inflAssctAftWqltTn);
minInflAssctBfrWqltTp = Math.min(minInflAssctBfrWqltTp, inflAssctBfrWqltTp);
mininflAssctBfrWqltToc = Math.min(mininflAssctBfrWqltToc, inflAssctBfrWqltToc);
mininflAssctBfrWqltSs = Math.min(mininflAssctBfrWqltSs, inflAssctBfrWqltSs);
minInflAssctAftWqltToc = Math.min(minInflAssctAftWqltToc, inflAssctAftWqltToc);
minInflAssctAftWqltSs = Math.min(minInflAssctAftWqltSs, inflAssctAftWqltSs);
minTpInflWqltBod = Math.min(minTpInflWqltBod, tpInflWqltBod);
minTpInflWqltTp = Math.min(minTpInflWqltTp, tpInflWqltTp);
@@ -170,11 +170,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
avgefflWqltToc += efflWqltToc;
avgEfflWqltSs += efflWqltSs;
avginflAssctBfrWqltBod += inflAssctBfrWqltBod;
avginflAssctBfrWqltTn += inflAssctBfrWqltTn;
avgInflAssctAftWqltBod += inflAssctAftWqltBod;
avgInflAssctAftWqltTn += inflAssctAftWqltTn;
avgInflAssctBfrWqltTp += inflAssctBfrWqltTp;
avginflAssctBfrWqltToc += inflAssctBfrWqltToc;
avginflAssctBfrWqltSs += inflAssctBfrWqltSs;
avgInflAssctAftWqltToc += inflAssctAftWqltToc;
avgInflAssctAftWqltSs += inflAssctAftWqltSs;
avgTpInflWqltBod += tpInflWqltBod;
avgTpInflWqltTp += tpInflWqltTp;
@@ -190,11 +190,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
efflWqltSs: filteredData.length==0?'0.0':(Math.round(avgEfflWqltSs / filteredData.length * 10) / 10).toFixed(1),
efflWqltTn: filteredData.length==0?'0.000':(Math.round(avgEfflWqltTn / filteredData.length * 1000) / 1000).toFixed(3),
efflWqltTp: filteredData.length==0?'0.000':(Math.round(avgEfflWqltTp / filteredData.length * 1000) / 1000).toFixed(3),
inflAssctBfrWqltBod: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltBod / filteredData.length * 10) / 10).toFixed(1),
inflAssctBfrWqltTn: filteredData.length==0?'0.000':(Math.round(avginflAssctBfrWqltTn / filteredData.length * 1000) / 1000).toFixed(3),
inflAssctAftWqltBod: filteredData.length==0?'0.0':(Math.round(avgInflAssctAftWqltBod / filteredData.length * 10) / 10).toFixed(1),
inflAssctAftWqltTn: filteredData.length==0?'0.000':(Math.round(avgInflAssctAftWqltTn / filteredData.length * 1000) / 1000).toFixed(3),
inflAssctBfrWqltTp: filteredData.length==0?'0.000':(Math.round(avgInflAssctBfrWqltTp / filteredData.length * 1000) / 1000).toFixed(3),
inflAssctBfrWqltToc: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltToc / filteredData.length * 10) / 10).toFixed(1),
inflAssctBfrWqltSs: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltSs / filteredData.length * 10) / 10).toFixed(1),
inflAssctAftWqltToc: filteredData.length==0?'0.0':(Math.round(avgInflAssctAftWqltToc / filteredData.length * 10) / 10).toFixed(1),
inflAssctAftWqltSs: filteredData.length==0?'0.0':(Math.round(avgInflAssctAftWqltSs / filteredData.length * 10) / 10).toFixed(1),
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -213,11 +213,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
efflWqltSs : Math.round(maxEfflWqltSs * 10) / 10?(Math.round(maxEfflWqltSs * 10) / 10).toFixed(1):'0.0',
efflWqltTn : Math.round(maxEfflWqltTn * 1000) / 1000?(Math.round(maxEfflWqltTn * 1000) / 1000).toFixed(3):'0.000',
efflWqltTp : Math.round(maxEfflWqltTp * 1000) / 1000?(Math.round(maxEfflWqltTp * 1000) / 1000).toFixed(3):'0.000',
inflAssctBfrWqltBod : Math.round(maxinflAssctBfrWqltBod * 10) / 10?(Math.round(maxinflAssctBfrWqltBod * 10) / 10).toFixed(1):'0.0',
inflAssctBfrWqltTn : Math.round(maxinflAssctBfrWqltTn * 1000) / 1000?(Math.round(maxinflAssctBfrWqltTn * 1000) / 1000).toFixed(3):'0.000',
inflAssctAftWqltBod : Math.round(maxInflAssctAftWqltBod * 10) / 10?(Math.round(maxInflAssctAftWqltBod * 10) / 10).toFixed(1):'0.0',
inflAssctAftWqltTn : Math.round(maxInflAssctAftWqltTn * 1000) / 1000?(Math.round(maxInflAssctAftWqltTn * 1000) / 1000).toFixed(3):'0.000',
inflAssctBfrWqltTp : Math.round(maxInflAssctBfrWqltTp * 1000) / 1000?(Math.round(maxInflAssctBfrWqltTp * 1000) / 1000).toFixed(3):'0.000',
inflAssctBfrWqltToc : Math.round(maxinflAssctBfrWqltToc * 10) / 10?(Math.round(maxinflAssctBfrWqltToc * 10) / 10).toFixed(1):'0.0',
inflAssctBfrWqltSs : Math.round(maxinflAssctBfrWqltSs * 10) / 10?(Math.round(maxinflAssctBfrWqltSs * 10) / 10).toFixed(1):'0.0',
inflAssctAftWqltToc : Math.round(maxInflAssctAftWqltToc * 10) / 10?(Math.round(maxInflAssctAftWqltToc * 10) / 10).toFixed(1):'0.0',
inflAssctAftWqltSs : Math.round(maxInflAssctAftWqltSs * 10) / 10?(Math.round(maxInflAssctAftWqltSs * 10) / 10).toFixed(1):'0.0',
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -236,11 +236,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
efflWqltSs : Math.round(minEfflWqltSs * 10) / 10?(Math.round(minEfflWqltSs * 10) / 10).toFixed(1) : '0.0',
efflWqltTn : Math.round(minEfflWqltTn * 1000) / 1000?(Math.round(minEfflWqltTn * 1000) / 1000).toFixed(3) : '0.000',
efflWqltTp : Math.round(minEfflWqltTp * 1000) / 1000?(Math.round(minEfflWqltTp * 1000) / 1000).toFixed(3) : '0.000',
inflAssctBfrWqltBod : Math.round(mininflAssctBfrWqltBod * 10) / 10?(Math.round(mininflAssctBfrWqltBod * 10) / 10).toFixed(1) : '0.0',
inflAssctBfrWqltTn : Math.round(mininflAssctBfrWqltTn * 1000) / 1000?(Math.round(mininflAssctBfrWqltTn * 1000) / 1000).toFixed(3) : '0.000',
inflAssctAftWqltBod : Math.round(minInflAssctAftWqltBod * 10) / 10?(Math.round(minInflAssctAftWqltBod * 10) / 10).toFixed(1) : '0.0',
inflAssctAftWqltTn : Math.round(minInflAssctAftWqltTn * 1000) / 1000?(Math.round(minInflAssctAftWqltTn * 1000) / 1000).toFixed(3) : '0.000',
inflAssctBfrWqltTp : Math.round(minInflAssctBfrWqltTp * 1000) / 1000?(Math.round(minInflAssctBfrWqltTp * 1000) / 1000).toFixed(3) : '0.000',
inflAssctBfrWqltToc : Math.round(mininflAssctBfrWqltToc * 10) / 10?(Math.round(mininflAssctBfrWqltToc * 10) / 10).toFixed(1) : '0.0',
inflAssctBfrWqltSs : Math.round(mininflAssctBfrWqltSs * 10) / 10?(Math.round(mininflAssctBfrWqltSs * 10) / 10).toFixed(1) : '0.0',
inflAssctAftWqltToc : Math.round(minInflAssctAftWqltToc * 10) / 10?(Math.round(minInflAssctAftWqltToc * 10) / 10).toFixed(1) : '0.0',
inflAssctAftWqltSs : Math.round(minInflAssctAftWqltSs * 10) / 10?(Math.round(minInflAssctAftWqltSs * 10) / 10).toFixed(1) : '0.0',
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -293,10 +293,10 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
copyYearList.forEach((item) => {
excelDownList.push({
날짜: item.msrDt,
"유입BOD(mg/L)": item.inflAssctBfrWqltBod,
"유입TOC(COD)(mg/L)": item.inflAssctBfrWqltToc,
"유입SS(mg/L)": item.inflAssctBfrWqltSs,
"유입TN(mg/L)": item.inflAssctBfrWqltTn,
"유입BOD(mg/L)": item.inflAssctAftWqltBod,
"유입TOC(COD)(mg/L)": item.inflAssctAftWqltToc,
"유입SS(mg/L)": item.inflAssctAftWqltSs,
"유입TN(mg/L)": item.inflAssctAftWqltTn,
"유입TP(mg/L)": item.inflAssctBfrWqltTp,
"유출BOD(mg/L)": item.efflWqltBod,
"유출TOC(COD)(mg/L)": item.efflWqltToc,
+4 -6
View File
@@ -7,7 +7,6 @@ import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import WaterQualityModal from "./modal/page";
import type { FacilityWaterQltyProps } from "@/app/store/facilityWaterQlty";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function ProcessFacilitySearch() {
const { Common
@@ -37,8 +36,7 @@ export default function ProcessFacilitySearch() {
upHeadList3,
facilityWaterQltyList,
facilityWaterQltyCount,
excelList,
isLoading,
excelList
} = FacilityWaterQltyMain;
const mainList: FacilityWaterQltyProps[] = facilityWaterQltyList || [];
@@ -50,7 +48,8 @@ export default function ProcessFacilitySearch() {
const [upheadList, setUpheadList] = useState<TableUpperProps[]>(upHeadList1);
const [fcltyName, setFcltyName] = useState<string>("");
const [operationValue, setOperationValue] = useState<string>("0");
const [searchYearValue, setSearchYearValue] = useState<string>(selectSearchYear[0]?.val || "0");
//const [searchYearValue, setSearchYearValue] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYearValue, setSearchYearValue] = useState<string>("2023");
const [fcltCpct, setFcltCpct] = useState<string>("0");
// 모달 상태 추가
@@ -134,7 +133,7 @@ export default function ProcessFacilitySearch() {
initializeCommonData();
searchFacilityWaterQltyList(1, 10, selectSearchYear[0]?.val || "0");
}
}, [isInit, initializeCommonData, searchFacilityWaterQltyList]);
}, [isInit, initializeCommonData, searchFacilityWaterQltyList, selectSearchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -188,7 +187,6 @@ export default function ProcessFacilitySearch() {
initClick={resetVal}
ref={ref} isAdmin={false} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"시설별 수질현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total<10?facilityWaterQltyList.length:total} resetPageNo={resetPage} onPageChange={handlePageChange} />
@@ -52,6 +52,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
return Number(value.replace(/,/g, ''));
};
console.log('filteredData : ', filteredData);
let maxtotInflAmnt = 0;
let maxinflAmnt = 0;
let maxsumFlow = 0;
+7 -8
View File
@@ -6,7 +6,6 @@ import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import FlowRateModal from "./modal/page";
import type { ExcelType } from "@/app/store/flowRate";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function ProcessFacilitySearch() {
const {Common
@@ -43,15 +42,15 @@ export default function ProcessFacilitySearch() {
upHeadList3,
flowRateList,
flowRateCount,
excelList,
isLoading,
excelList
} = FlowRateList;
// 입력값 상태 관리
const [fcltCpct, setFcltCpct] = useState<string>("0");
const [fcltyName, setFcltyName] = useState<string>("");
const [operationValue, setOperationValue] = useState<string>("0");
const [searchYearValue, setSearchYearValue] = useState<string>(selectSearchYear[0]?.val || "0");
//const [searchYearValue, setSearchYearValue] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYearValue, setSearchYearValue] = useState<string>("2023");
const [widthSize, setWidthSize] = useState<string>("w-[120%]");
const [upheadList, setUpheadList] = useState<TableUpperProps[]>(upHeadList1);
const [resetPage, setResetPage] = useState<boolean>(false);
@@ -90,9 +89,9 @@ export default function ProcessFacilitySearch() {
setWidthSize("w-[120%]");
setUpheadList(upHeadList1)
// 상태값 설정
setSearchYearValue(selectSearchYear[0]?.val || "0");
setFcltCpct(selectUpdownData[0]?.val || "0");
setOperationValue(selectOperationData[0]?.val || "0");
setSearchYearValue(selectSearchYear[0]?.val || "0");
// SearchInputSelect 초기화
setFcltyName("");
if (searchInputRef.current) {
@@ -127,10 +126,11 @@ export default function ProcessFacilitySearch() {
// 시도 데이터 초기화
useEffect(() => {
if(!isInit) {
console.log('searchYearValue', searchYearValue, isInit);
initializeCommonData();
searchFlowRateList(1, 10, selectSearchYear[0]?.val || "0");
searchFlowRateList(1, 10, searchYearValue || "0");
}
}, [isInit, initializeCommonData, searchFlowRateList]);
}, [isInit, initializeCommonData, searchFlowRateList, searchYearValue]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -189,7 +189,6 @@ export default function ProcessFacilitySearch() {
initClick={resetVal}
ref={ref} isAdmin={false} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"시설별 유량현황"} tableData={flowRateList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
+7 -21
View File
@@ -13,11 +13,7 @@ interface FeatureData {
}
interface MapInstance {
getLayers: () => {
getArray: () => Array<{
getSource?: () => { getFeatureById?: (id: string) => FeatureData | null };
}>;
};
getLayers: () => { getArray: () => Array<{ getSource?: () => { getFeatureById?: (id: string) => FeatureData | null } }> };
getView: () => { fit: (extent: number[], options: object) => void };
}
@@ -30,20 +26,20 @@ const Map = () => {
const fetchData = async () => {
try {
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}/v1/map`;
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}/v1/map`
const reqUrl = `${API_URL}/lyrStngs/FO_NETWORK`;
const response = await fetch(reqUrl, {
method: "GET",
headers: {
accept: "application/json",
},
}
});
if (!response.ok) {
throw new Error(`HTTP 오류! 상태: ${response.status}`);
}
const data = await response.json(); // 여기서 json 파싱
const data = await response.json(); // 여기서 json 파싱
setTreeData(data); // 데이터 설정
} catch (error) {
console.error("데이터 불러오기 실패:", error);
@@ -64,12 +60,7 @@ const Map = () => {
}
// 항상 같은 select 객체 사용
const select = GisApp.Module.select as unknown as
| {
resetSelectedFeature: () => void;
selectFeature: (feature: FeatureData, selected: boolean) => void;
}
| undefined;
const select = (GisApp.Module.select as unknown) as { resetSelectedFeature: () => void; selectFeature: (feature: FeatureData, selected: boolean) => void } | undefined;
if (!select) return;
// 1. 기존 선택 초기화
@@ -124,12 +115,9 @@ const Map = () => {
};
// onCheckedLayersChange handler
const handleCheckedLayersChange = (
checkedIds: string[],
checkedNodesData: unknown[]
) => {
const handleCheckedLayersChange = (checkedIds: string[], checkedNodesData: unknown[]) => {
// Handle checked layers change if needed
console.log("Checked layers changed:", checkedIds, checkedNodesData);
console.log('Checked layers changed:', checkedIds, checkedNodesData);
};
return (
@@ -149,8 +137,6 @@ const Map = () => {
isOpen={isOpen}
isSearchModalOpen={isSearchModalOpen}
onCheckedLayersChange={handleCheckedLayersChange}
imgVisble={false}
searchBar={undefined}
/>
</div>
);
+5 -8
View File
@@ -4,7 +4,6 @@ import type { TableUpperProps } from "@/app/store/common";
import { downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components";
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function PlanSewage() {
const {Common
@@ -38,8 +37,7 @@ export default function PlanSewage() {
upHeadList3,
planSewageList,
planSewageCount,
excelList,
isLoading,
excelList
} = PlanSewage;
const ref = useRef<ReturnType>({
@@ -72,7 +70,8 @@ export default function PlanSewage() {
// 시설상태
const [operationValue, setOperationValue] = useState<string>("0");
// 조회기간
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
//const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYear, setSearchYear] = useState<string>("2023");
/**
* 페이지 함수
@@ -93,7 +92,6 @@ export default function PlanSewage() {
input.value = "";
}
}
searchPlanSewageList(1, 10, selectSearchYear[0]?.val || "0", ref.current.partValue);
}
/**
@@ -102,9 +100,9 @@ export default function PlanSewage() {
useEffect(() => {
if (!isInit) {
initializeCommonData();
searchPlanSewageList(1, 10, selectSearchYear[0]?.val || "0", ref.current.partValue);
searchPlanSewageList(1, 10, searchYear, ref.current.partValue);
}
}, [isInit, initializeCommonData, searchPlanSewageList]);
}, [isInit, initializeCommonData, searchYear, searchPlanSewageList]);
useEffect(() => {
console.log('excelList' , excelList);
@@ -189,7 +187,6 @@ export default function PlanSewage() {
initClick={resetVal}
ref={ref} isAdmin={false}/>
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={ undefined } headName={"계획하수량 산정지표 현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
+4 -7
View File
@@ -4,7 +4,6 @@ import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SelectBox, Title,
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import ProcessFacilityInfoModal from "./modal/page";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function ProcessArea() {
const {Common,
@@ -40,8 +39,7 @@ export default function ProcessArea() {
upHeadList1,
processAreaList,
processAreaCount,
excelList,
isLoading,
excelList
} = ProcessArea;
const mainList: Record<string, unknown>[] = processAreaList || [];
@@ -86,7 +84,7 @@ export default function ProcessArea() {
}
}
setSearchYearValue(selectSearchYear[0]?.val || "0");
searchProcessAreaList(1, 10, '', '', selectSearchYear[0]?.val || "0");
searchProcessAreaList(1, 10, '', '', selectSearchYear[0]?.val);
}
// 셀 클릭 시 모달 표시
@@ -106,9 +104,9 @@ export default function ProcessArea() {
useEffect(() => {
if (!isInit) {
initializeCommonData();
searchProcessAreaList(1, 10, '', '', selectSearchYear[0]?.val || "0");
searchProcessAreaList(1, 10, '', '', selectSearchYear[0]?.val);
}
}, [isInit, initializeCommonData, searchProcessAreaList]);
}, [isInit, initializeCommonData, searchProcessAreaList, selectSearchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -154,7 +152,6 @@ export default function ProcessArea() {
isAdmin={true}
/>
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className="w-[180%]">
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
+1 -4
View File
@@ -5,7 +5,6 @@ import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, Selec
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import ProcessFacilityInfoModal from "./modal/page";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function ProcessFacilitySearch() {
const {Common
@@ -64,8 +63,7 @@ export default function ProcessFacilitySearch() {
upHeadList1,
upHeadList2,
upHeadList3,
excelList,
isLoading,
excelList
} = ProcessFacilityList;
const processFacilityList = ProcessFacilityList?.processFacilityList || [];
@@ -264,7 +262,6 @@ export default function ProcessFacilitySearch() {
initClick={resetVal}
ref={ref} isAdmin={false} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable
+2 -8
View File
@@ -4,7 +4,6 @@ import type { TableUpperProps } from "@/app/store/common";
import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components";
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function Rdi() {
const {Common
@@ -39,7 +38,6 @@ export default function Rdi() {
rdiList,
rdiCount,
excelList,
isLoading,
} = Rdi;
const ref = useRef<ReturnType>({
@@ -72,10 +70,6 @@ export default function Rdi() {
// 조회기간
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
useEffect(() => {
console.log(isLoading);
}, [isLoading]);
/**
* 페이지 함수
*/
@@ -97,6 +91,7 @@ export default function Rdi() {
}
}
searchRdiList(1, 10, selectSearchYear[0]?.val || "0");
}
/**
@@ -107,7 +102,7 @@ export default function Rdi() {
initializeCommonData();
searchRdiList(1, 10, selectSearchYear[0]?.val || "0");
}
}, [isInit, initializeCommonData, searchRdiList]);
}, [isInit, initializeCommonData, searchRdiList, selectSearchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -192,7 +187,6 @@ export default function Rdi() {
initClick={resetVal}
ref={ref} isAdmin={false} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={ undefined } headName={"RDII추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
@@ -30,11 +30,6 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
setDetailList(gridListSewageOccurDetail);
}, [gridListSewageOccurDetail]);
useEffect(() => {
searchSewageOccurDetailList(props.facilityCd, validSearchYear, startYearMonth, endYearMonth);
}, [startYearMonth, endYearMonth]);
return (
<>
<ListDiv className="!h-[80px] !mt-10">
@@ -62,7 +57,6 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
}}
selectClass="ml-5 w-[100px]"
startYear={1900}
yearReadOnly={true}
/>~
<DateMonthPicker
field={{
@@ -80,7 +74,6 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
}}
selectClass="ml-5 w-[100px]"
startYear={1900}
yearReadOnly={true}
/>
</TableCell>
</TableRow>
+5 -8
View File
@@ -6,7 +6,6 @@ import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import SewageOccurModal from "./modal/page";
import type { SewageOccurProps } from "@/app/store/sewageOccur";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function PlanSewage() {
const {Common
@@ -47,8 +46,7 @@ export default function PlanSewage() {
upHeadList3,
sewageOccurList,
sewageOccurCount,
excelList,
isLoading,
excelList
} = SewageOccur;
const ref = useRef<ReturnType>({
@@ -86,7 +84,8 @@ export default function PlanSewage() {
// 시설상태
const [operationValue, setOperationValue] = useState<string>("0");
// 조회기간
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
// const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYear, setSearchYear] = useState<string>("2023");
/**
* 페이지 함수
@@ -107,7 +106,6 @@ export default function PlanSewage() {
input.value = "";
}
}
searchSewageOccurList(1, 10, selectSearchYear[0]?.val || "0");
}
// 모달 닫기
@@ -130,9 +128,9 @@ export default function PlanSewage() {
useEffect(() => {
if (!isInit) {
initializeCommonData();
searchSewageOccurList(1, 10, selectSearchYear[0]?.val || "0");
searchSewageOccurList(1, 10, searchYear || "0");
}
}, [isInit, initializeCommonData, searchSewageOccurList]);
}, [isInit, initializeCommonData, searchSewageOccurList, searchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -219,7 +217,6 @@ export default function PlanSewage() {
isAdmin={false}
/>
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"오수발생량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
@@ -116,6 +116,7 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}
}, [searchYear, tabTerm]);
useEffect(()=>{
console.log(fcltyName, searchYear);
unserWaterModal(fcltyName, searchYear);
}, [])
useEffect(() => {
@@ -163,7 +164,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
/>
<h3 className="justify-center px-5">~</h3>
<DateMonthPicker
@@ -175,7 +175,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
/>
</div>
</TableCell>
@@ -228,8 +227,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
enableMonth={['6월', '7월', '8월']}
/>
<h3 className="justify-center px-5">~</h3>
<DateMonthPicker
@@ -241,8 +238,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
enableMonth={['6월', '7월', '8월']}
/>
</div>
</TableCell>
@@ -286,8 +281,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
enableMonth={['1월', '2월']}
/>
<h3 className="justify-center px-5">~</h3>
<DateMonthPicker
@@ -299,8 +292,6 @@ export default function UnderWaterInputModal({fcltyName='', searchYear=new Date(
}}
selectClass="ml-5 w-[100px]"
startYear={Number(searchYear)} // 시작 연도 설정
yearReadOnly={true}
enableMonth={['1월', '2월']}
/>
</div>
</TableCell>
+3 -5
View File
@@ -6,7 +6,6 @@ import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
import UnderWaterInputModal from "./modal/page";
import type { UnderWaterProps } from "@/app/store/underWaterInput/types";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function UnderWaterInput() {
const {Common
@@ -47,7 +46,6 @@ export default function UnderWaterInput() {
underWaterList,
underWaterCount,
excelList,
isLoading,
} = UnderWater;
const ref = useRef<ReturnType>({
@@ -84,7 +82,8 @@ export default function UnderWaterInput() {
// 시설상태
const [operationValue, setOperationValue] = useState<string>("0");
// 조회기간
const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
//const [searchYear, setSearchYear] = useState<string>(selectSearchYear[0]?.val || "0");
const [searchYear, setSearchYear] = useState<string>("2023");
/**
* 페이지 함수
@@ -129,7 +128,7 @@ export default function UnderWaterInput() {
initializeCommonData();
searchUnderWaterList(1, 10, selectSearchYear[0]?.val || "0");
}
}, [isInit, initializeCommonData, searchUnderWaterList]);
}, [isInit, initializeCommonData, searchUnderWaterList, selectSearchYear]);
useEffect(() => {
if (excelList && excelList.length > 0) {
@@ -216,7 +215,6 @@ export default function UnderWaterInput() {
isAdmin={false}
/>
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll">
<div className={widthSize}>
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"지하수유입량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} />
+1 -23
View File
@@ -2,7 +2,7 @@
* 보편적으로 쓰는 store 공간
====================================**/
import { getFetch, getFetchAreaList } from "@/app/components/api";
import { getFetch } from "@/app/components/api";
/**
* STORE - TYPE
@@ -205,28 +205,6 @@ const selectMiddleRegionData: SelectDataType[] = [
* STORE - API
*/
// 처리시설 계획정보 호출 (알에스원)
export const planInfoUrl = 'https://apigateway.apps.rsonesoft.com/dc-service/api/v1/nowDmgMtncGnsvy';
export const fetchPlanInfo = async (targetYear : string | undefined, ctpvNm : string | undefined, sggNm : string | undefined, fcltyCd : string | undefined) => {
try {
const baseUrl = planInfoUrl;
const queryParams = new URLSearchParams();
if (ctpvNm && ctpvNm !== '전체') queryParams.append('ctpvNm', ctpvNm);
if (sggNm && sggNm !== '전체') queryParams.append('sggNm', sggNm);
if (targetYear) queryParams.append('targetYear',targetYear);
if (fcltyCd) queryParams.append('swtrmtFcltCd', fcltyCd);
const queryString = queryParams.toString();
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
const res = await getFetchAreaList(url);
return res;
} catch (error) {
console.error('처리시설 계획정보를 가져오는데 실패했습니다:', error);
return [];
}
}
// 시도 API 호출 함수 추가
const fetchSidoData = async (): Promise<SelectDataType[]> => {
try {
+283 -392
View File
@@ -2,11 +2,9 @@
* Store - 타입
*/
import { getFetch } from "@/app/components/api";
import { getFetch, getFetchAreaList } from "@/app/components/api";
import DataForm from "@/app/components/common/DataForm";
import { fetchPlanInfo } from "../common";
import type { FacilityWaterQltyProps } from "../facilityWaterQlty";
import { calRainEffectDay, type ApiResponse, type FlowDataItem } from "../underWaterInput";
// selectBox
export type SelectDataType = {
@@ -113,13 +111,13 @@ export interface RainManageListProps {
sggNm?: string,
addr?: string,
fctCpc?: number,
inflAssctBfrWqltBod: number | '',
inflAssctBfrWqltToc: number | '',
inflAssctBfrWqltSs: number | '',
inflAssctBfrWqltTn: number | '',
inflAssctBfrWqltTp: number | '',
inflAssctAftWqltBod: number | '',
inflAssctAftWqltToc: number | '',
inflAssctAftWqltSs: number | '',
inflAssctAftWqltTn: number | '',
inflAssctAftWqltTp: number | '',
efflWqltBod: number | '',
efflWqltToc: number | '',
efflWqltCod: number | '',
efflWqltSs: number | '',
efflWqltTn: number | '',
efflWqltTp: number | '',
@@ -145,7 +143,6 @@ export interface RainManageListProps {
dsInflWqltTn: number | '',
dsInflWqltTp: number | '',
extnsSeqno?: number | '',
rainEffectDay?: number | '',
}
export interface RainManageExcelType {
@@ -367,14 +364,14 @@ const upHeadListRainManage : TableUpperProps[] = [
{ id: "dsInflWqltTn", title: "T-N", row:1 },
{ id: "dsInflWqltTp", title: "T-P", row:1 },
{ id: "C", title: "유입수질(㎎/L)", row:0, colSpan:5 },
{ id: "inflAssctBfrWqltBod", title: "BOD", row:1 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)", row:1 },
{ id: "inflAssctBfrWqltSs", title: "SS", row:1 },
{ id: "inflAssctBfrWqltTn", title: "T-N", row:1 },
{ id: "inflAssctBfrWqltTp", title: "T-P", row:1 },
{ id: "inflAssctAftWqltBod", title: "BOD", row:1 },
{ id: "inflAssctAftWqltToc", title: "TOC\n(COD)", row:1 },
{ id: "inflAssctAftWqltSs", title: "SS", row:1 },
{ id: "inflAssctAftWqltTn", title: "T-N", row:1 },
{ id: "inflAssctAftWqltTp", title: "T-P", row:1 },
{ id: "D", title: "방류수질(㎎/L)", row:0, colSpan:5 },
{ id: "efflWqltBod", title: "BOD", row:1 },
{ id: "efflWqltToc", title: "TOC\n(COD)", row:1 },
{ id: "efflWqltCod", title: "TOC\n(COD)", row:1 },
{ id: "efflWqltSs", title: "SS", row:1 },
{ id: "efflWqltTn", title: "T-N", row:1 },
{ id: "efflWqltTp", title: "T-P", row:1 },
@@ -690,20 +687,20 @@ const drainageEquipmentList : DrainageEquipmentListProps[] = [
* Store - api (데이터 호출)
====================================*/
/* 시설정보 및 운영현황 - 계획 */
const fetchFacilityPlan = async (targetYear : string | undefined, fcltyCd : string | undefined, set : (fn: (state: DashBoardType) => DashBoardType) => void) => {
const fetchFacilityPlan = async (targetYear : string | undefined, fcltyCd : string | undefined) => {
try {
const res = await fetchPlanInfo(undefined, undefined, undefined, fcltyCd);
return res;
targetYear = targetYear ? targetYear : "2023";
const baseUrl = 'https://apigateway.rsonesoft.com/dc-service/api/v1/nowDmgMtncGnsvy';
const queryParams = new URLSearchParams();
if (fcltyCd) queryParams.append('swtrmtFcltCd', fcltyCd);
//if (targetYear) queryParams.append('targetYear',targetYear);
const queryString = queryParams.toString();
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
const res = await getFetchAreaList(url);
return res
} catch (error) {
console.error('시설계획정보를 가져오는데 실패했습니다:', error);
set((state) => ({
...state,
PlanFclty : {
...state.PlanFclty,
isLoadingPlanFclty : false,
isLoadingOperationStatus : false
}
}));
return {data: [], count: 0};
}
};
@@ -732,6 +729,20 @@ const fetchMainGraph = async (searchYear: string|undefined, fcltyCd: string|unde
}
}
// 배수설비 정비현황
const fetchDrainageEquipment = async (searchYear: string|undefined, fcltyCd: string|undefined) => {
try{
/* const url = '/fclt/qlty/hist/' + (searchYear?searchYear:'2024') + '/' + (fcltyCd?fcltyCd:'11680PB001R');
const res = await getFetch('fo', url);
return { data: res.data, count: res.count } */
console.log(searchYear, fcltyCd);
return { data : drainageEquipmentList, count : drainageEquipmentList.length }
} catch (error) {
console.error('배수설비 정비현황 데이터를 가져오는데 실패했습니다:', error);
return { data: [], count: 0 };
}
}
/**====================================
* Store - action
====================================*/
@@ -745,6 +756,8 @@ export type DashBoardActions = {
searchMainGraph(searchYear: string, fcltyCd: string): Promise<void>;
/**강우일 운영현황 */
searchRainManage(searchYear: string, fcltyCd: string, isExcel: boolean): Promise<void>;
/**배수설비 정비현황 */
searchDrainageEquipment(searchYear: string, fcltyCd: string, isExcel: boolean): Promise<void>;
}
export type DashBoardType = {
@@ -764,17 +777,12 @@ export type DashBoardType = {
planYearList : string[];
upHeadListPlanFclty : TableUpperProps[];
planFcltyList : planFcltyListProps[];
waterUsage1 : number | '',
waterUsage2 : number | '',
waterUsage3 : number | '',
isLoadingPlanFclty : boolean;
},
OperationStatus : {
isInit : boolean;
upHeadListOperationStatus : TableUpperProps[];
operationalStatusList : OperationalStatusListProps[];
isLoadingOperationStatus : boolean;
}
MainGraph : {
@@ -788,7 +796,6 @@ export type DashBoardType = {
chart_efflTn : lineChartDataProps[];
chart_inflBod : lineChartDataProps[];
chart_efflBod : lineChartDataProps[];
isLoadingMainGraph : boolean;
},
RainManage : {
@@ -796,7 +803,6 @@ export type DashBoardType = {
upHeadListRainManage : TableUpperProps[];
rainManageList : RainManageListProps[];
excelList : RainManageExcelType[];
isLoadingRainManage : boolean;
},
DrainageEquipment : {
@@ -825,18 +831,13 @@ export const dashBoardInitState:DashBoardType = {
isInit : true,
planYearList : planYearList,
upHeadListPlanFclty : upHeadListPlanFclty,
planFcltyList : planFcltyList,
waterUsage1 : 0,
waterUsage2 : 0,
waterUsage3 : 0,
isLoadingPlanFclty : false,
planFcltyList : planFcltyList
},
OperationStatus : {
isInit : false,
upHeadListOperationStatus : upHeadListOperationStatus,
operationalStatusList : operationalStatusList,
isLoadingOperationStatus : false,
operationalStatusList : operationalStatusList
},
MainGraph : {
@@ -849,16 +850,14 @@ export const dashBoardInitState:DashBoardType = {
chart_inflTn : chart_inflTn,
chart_efflTn : chart_efflTn,
chart_inflBod : chart_inflBod,
chart_efflBod : chart_efflBod,
isLoadingMainGraph : false,
chart_efflBod : chart_efflBod
},
RainManage : {
isInit : false,
upHeadListRainManage : upHeadListRainManage,
rainManageList : rainManageList,
excelList : [],
isLoadingRainManage : false,
excelList : []
},
DrainageEquipment : {
@@ -927,106 +926,18 @@ const changeValue=(operationalStatus, data, keyTxt = 'INFL_AMNT')=>{
const calcValue = (operationalStatus, data, keyTxt='INFL_ASSCT_BFR_WQLT_TP') => {
// 연간
operationalStatus.yearAvg = data.yearData && data.yearData['AVG_'+keyTxt] ? Number(Math.round(data.yearData['AVG_'+keyTxt] * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.yearMax = data.yearData && data.yearData['MAX_'+keyTxt] ? Number(Math.round(data.yearData['MAX_'+keyTxt] * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.yearMin = data.yearData && data.yearData['MIN_'+keyTxt] ? Number(Math.round(data.yearData['MIN_'+keyTxt] * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.yearAvg = data.yearData ? Number(Math.round(data.yearData['AVG_'+keyTxt] * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.yearMax = data.yearData ? Number(Math.round(data.yearData.MAX_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.yearMin = data.yearData ? Number(Math.round(data.yearData.MIN_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
// 여름
operationalStatus.summerAll = data.summer && data.summer['AVG_'+keyTxt] ? Number(Math.round(data.summer['AVG_'+keyTxt] * 0.8 * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.summerThree = data.summerRainy && data.summerRainy['AVG_'+keyTxt] ? Number(Math.round(data.summerRainy['AVG_'+keyTxt] * 0.82 * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.summerRain = data.summerSunny && data.summerSunny['AVG_'+keyTxt] ? Number(Math.round(data.summerSunny['AVG_'+keyTxt] * 0.74 * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.summerAll = data.summer ? Number(Math.round(data.summer.AVG_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.summerThree = data.summerRainy ? Number(Math.round(data.summerRainy.AVG_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.summerRain = data.summerSunny ? Number(Math.round(data.summerSunny.AVG_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
// 겨울
operationalStatus.winterAll = data.winter && data.winter['AVG_'+keyTxt] ? Number(Math.round(data.winter['AVG_'+keyTxt] * 1.16*1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyMin = data.winterSunny && data.winterSunny['MIN_'+keyTxt] ? Number(Math.round(data.winterSunny['MIN_'+keyTxt] * 1.2 * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyAvg = data.winterSunny && data.winterSunny['AVG_'+keyTxt] ? Number(Math.round(data.winterSunny['AVG_'+keyTxt] * 1.25 *1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyMax = data.winterSunny && data.winterSunny['MAX_'+keyTxt] ? Number(Math.round(data.winterSunny['MAX_'+keyTxt] * 1.3 *1000) / 1000).toFixed(3).toString() : '';
}
type RtnFlowType = {
inflAmnt: string | number;
infoRnDay: string | number;
bscFctCd: string;
msrDt: string;
}
type RtnFlowResponse = {
data: RtnFlowType[];
count: number;
}
const searchWaterUsage = async (searchYear: string, fcltyCd: string) => {
const waterUsage = [0, 0, 0];
for (let i = 0; i < 3; i++) {
try {
const res = await getFetch('fo', '/fclt/flow/' + fcltyCd + '/' + (Number(searchYear)-i)) as RtnFlowResponse;
let totWaterUsage = 0;
if (res && res.data && Array.isArray(res.data)) {
res.data.forEach((item: RtnFlowType) => {
totWaterUsage += Number(item.inflAmnt);
});
if (res.count > 0) {
const avg = totWaterUsage / res.count;
waterUsage[i] = parseFloat((avg * 0.65).toFixed(2));
}
}
} catch (error) {
console.error(`Error fetching water usage for year ${Number(searchYear)-i}:`, error);
waterUsage[i] = 0;
}
}
return waterUsage;
}
// 강우영향일 계산 및 강우량 덮어씌우기
export const calRainEffectDayRainManage = (data: RainManageListProps[]) => {
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
for(let idx = 0; idx < data.length; idx++) {
const item = data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay) >= 3) {
item.rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
}
}
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < data.length; idx++) {
if(data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < data.length; idx++) {
if(data[idx] && data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if(data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) {
data[idx]!.infoRnDay = data[idx-1]!.infoRnDay;
}
}
if(idx > 2){
if(data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) {
data[idx]!.infoRnDay = data[idx-2]!.infoRnDay;
}
}
}
}
let rtnData : RainManageListProps[] = [];
rtnData = data.filter((item: RainManageListProps) => item.rainEffectDay === 1);
return rtnData;
operationalStatus.winterAll = data.winter ? Number(Math.round(data.winter.AVG_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyMin = data.winterSunny ? Number(Math.round(data.winterSunny.MIN_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyAvg = data.winterSunny ? Number(Math.round(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
operationalStatus.winterSunnyMax = data.winterSunny ? Number(Math.round(data.winterSunny.MAX_INFL_ASSCT_BFR_WQLT_TP * 1000) / 1000).toFixed(3).toString() : '';
}
export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) => void)=>DashBoardActions=(set: (fn: (state: DashBoardType) => DashBoardType) => void) => {
@@ -1043,28 +954,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
/** 시설정보 및 운영현황 - 계획정보 */
searchPlanInfo : async (targetYear: string, fcltyCd: string) => {
set((state: DashBoardType) => ({
...state,
PlanFclty: {
...state.PlanFclty,
isLoadingPlanFclty: true,
},
}));
let waterUsage = [0, 0, 0];
waterUsage = await searchWaterUsage(targetYear, fcltyCd);
set((state: DashBoardType) => ({
...state,
PlanFclty : {
...state.PlanFclty,
waterUsage1 : waterUsage[0] || 0,
waterUsage2 : waterUsage[1] || 0,
waterUsage3 : waterUsage[2] || 0,
},
}));
const res = await fetchFacilityPlan(targetYear, fcltyCd, set);
const res = await fetchFacilityPlan(targetYear, fcltyCd);
let minDiff=9999999;
let minIndex;
res.forEach((el:any, idx) => {
@@ -1114,31 +1004,21 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
// 임시시
dataFormSettingPlan(el);
console.log('planFcltyList', planFcltyList);
console.log('rtnPlanData', rtnPlanData);
set((state: DashBoardType) => ({
...state,
PlanFclty: {
...state.PlanFclty,
planFcltyList: planFcltyList,
isLoadingPlanFclty: false,
},
}));
});
set((state: DashBoardType) => ({
...state,
PlanFclty : {
...state.PlanFclty,
planFcltyList : planFcltyList
}
}));
},
/** 시설정보 및 운영현황 - 운영실태 */
searchOperationStatus: async (isExcel: boolean, searchYear: string, fcltyCd: string) => {
set((state: DashBoardType) => ({
...state,
OperationStatus: {
...state.OperationStatus,
isLoadingOperationStatus: true,
},
}));
const res = await fetchOperationStatus(searchYear, fcltyCd);
const data = res.data;
if(data && operationalStatusList){
// 유량 - 유입
if (operationalStatusList?.[0]) {
@@ -1170,56 +1050,10 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
operationalStatusList[0].winterSunnyMin = data.winterSunny === null ? '' : (data.winterSunny.MIN_INFL_AMNT ? data.winterSunny.MIN_INFL_AMNT : 0) + (data.winterSunny.MIN_SUM_FLOW ? data.winterSunny.MIN_SUM_FLOW : 0) + (data.winterSunny.MIN_TP_INFL_WQLT_TP ? data.winterSunny.MIN_TP_INFL_WQLT_TP : 0);
operationalStatusList[0].winterSunnyAvg = data.winterSunny === null ? '' : (data.winterSunny.AVG_INFL_AMNT ? data.winterSunny.AVG_INFL_AMNT : 0) + (data.winterSunny.AVG_SUM_FLOW ? data.winterSunny.AVG_SUM_FLOW : 0) + (data.winterSunny.AVG_TP_INFL_WQLT_TP ? data.winterSunny.AVG_TP_INFL_WQLT_TP : 0);
operationalStatusList[0].winterSunnyMax = data.winterSunny === null ? '' : (data.winterSunny.MAX_INFL_AMNT ? data.winterSunny.MAX_INFL_AMNT : 0) + (data.winterSunny.MAX_SUM_FLOW ? data.winterSunny.MAX_SUM_FLOW : 0) + (data.winterSunny.MAX_TP_INFL_WQLT_TP ? data.winterSunny.MAX_TP_INFL_WQLT_TP : 0);
// 연계처리수,지하수유입량
const bscFctCd = fcltyCd;
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as ApiResponse;
const calData = calRainEffectDay(res2.data, 'SUNNY');
let chungcunSumFlow = 0;
let sumSummerChungcunDay = 0;
let sumSummerChungcunFlow = 0;
let sumWinterChungcunDay = 0;
let sumWinterChungcunFlow = 0;
/* let yearSumFlow = 0;
let summerSumFlow = 0;
let winterSumFlow = 0; */
calData.forEach((flowItem: FlowDataItem) => {
chungcunSumFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
//yearSumFlow += flowItem.sumFlow && flowItem.sumFlow !== 'x' ? Number(flowItem.sumFlow.toString().trim()) : 0;
if(flowItem.msrDt.substring(4,6) ==='06' || flowItem.msrDt.substring(4,6) ==='07' || flowItem.msrDt.substring(4,6) ==='08'){
sumSummerChungcunDay += 1;
sumSummerChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
//summerSumFlow += flowItem.sumFlow && flowItem.sumFlow !== 'x' ? Number(flowItem.sumFlow.toString().trim()) : 0;
}else if(flowItem.msrDt.substring(4,6) ==='01' || flowItem.msrDt.substring(4,6) ==='02'){
sumWinterChungcunDay += 1;
sumWinterChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
// winterSumFlow += flowItem.sumFlow && flowItem.sumFlow !== 'x' ? Number(flowItem.sumFlow.toString().trim()) : 0;
}
});
// 연계처리수
/* const avgYearSumFlow = yearSumFlow / calData.length;
const avgSummerSumFlow = summerSumFlow / calData.length;
const avgWinterSumFlow = winterSumFlow / calData.length; */
// 지하수유입량
const usage = chungcunSumFlow / calData.length;
const summerUsage = sumSummerChungcunFlow / sumSummerChungcunDay;
const winterUsage = sumWinterChungcunFlow / sumWinterChungcunDay;
operationalStatusList[0].groundWaterAvg = Math.round((usage-(usage*0.65*0.8)) * 100) / 100;
operationalStatusList[0].groundWaterSummer = Math.round((summerUsage-(summerUsage*0.65*0.8)) * 100) / 100;
operationalStatusList[0].groundWaterWinter = Math.round((winterUsage-(winterUsage*0.65*0.8)) * 100) / 100;
//operationalStatusList[0].groundWaterAvg = calData.length === 0 ? '' : Number(calData[0].inflAmnt) - (Number(calData[0].inflAmnt)*0.65*0.8);
//operationalStatusList[0].groundWaterSummer = calData.length === 0 ? '' : Number(calData[0].inflAmnt) - (Number(calData[0].inflAmnt)*0.65*0.8);
//operationalStatusList[0].groundWaterWinter = calData.length === 0 ? '' : Number(calData[0].inflAmnt) - (Number(calData[0].inflAmnt)*0.65*0.8);
// 지하수
operationalStatusList[0].groundWaterAvg = data.yearData.AVG_INFL_AMNT === null ? '' : Number(data.yearData.AVG_INFL_AMNT) - (Number(data.yearData.AVG_INFL_AMNT)*0.65*0.8);
operationalStatusList[0].groundWaterSummer = data.summer.AVG_INFL_AMNT === null ? '' : Number(data.summer.AVG_INFL_AMNT) - (Number(data.summer.AVG_INFL_AMNT)*0.65*0.8);
operationalStatusList[0].groundWaterWinter = data.winter.AVG_INFL_AMNT === null ? '' : Number(data.winter.AVG_INFL_AMNT) - (Number(data.winter.AVG_INFL_AMNT)*0.65*0.8);
// 오염물질
// RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD))
@@ -1229,13 +1063,16 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
const summerLowRain = data.summerBod&&data.summerBod.INFO_RN_DAY&&data.summerBod.INFO_RN_DAY!='null'?Number(data.summerBod.INFO_RN_DAY):0;
operationalStatusList[0].rdi = winterAvgBod===0?0:summerLowFlow * ((winterAvgBod - summerLowBod) / winterAvgBod);
operationalStatusList[0].rdiRain = summerLowRain;
dataFormSetting(operationalStatusList[0]);
}
if(operationalStatusList[0] && operationalStatusList[7]){
operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : data.yearData && data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg) / (data.yearData && data.yearData.AVG_INFL_AMNT ? Number(data.yearData.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer && data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer) / (data.summer && data.summer.AVG_INFL_AMNT ? Number(data.summer.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter && data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter) / (data.winter && data.winter.AVG_INFL_AMNT ? Number(data.winter.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
operationalStatusList[7].rdi = operationalStatusList[0].rdi === null ? '' : data.summerBod && data.summerBod.INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].rdi) / (data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0) * 100) * 10) / 10+'%';
console.log(Number(operationalStatusList[0].groundWaterAvg)+' '+Number(data.yearData.AVG_INFL_AMNT));
console.log(Number(operationalStatusList[0].groundWaterSummer)+' '+Number(data.summer.AVG_INFL_AMNT));
console.log(Number(operationalStatusList[0].groundWaterWinter)+' '+Number(data.winter.AVG_INFL_AMNT));
operationalStatusList[7].groundWaterAvg = Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT) * 100;
operationalStatusList[7].groundWaterSummer = Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT) * 100;
operationalStatusList[7].groundWaterWinter = Number(operationalStatusList[0].groundWaterWinter) / Number(data.winter.AVG_INFL_AMNT) * 100;
/* operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : Number(Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT)) * 100;
operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : Number(Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT)) * 100;
operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : Number(Number(operationalStatusList[0].groundWaterWinter) / Number(data.winter.AVG_INFL_AMNT)) * 100;*/
@@ -1243,7 +1080,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
}
for(let i=1; i<operationalStatusList.length; i++){
const txtArray = ['1', 'INFL_AMNT', 'SUM_FLOW', 'RETURN_AMNT', 'EFFL_AMNT', 'INFL_ASSCT_BFR_WQLT_BOD', 'EFFL_WQLT_BOD', 'INFL_ASSCT_BFR_WQLT_TN', 'EFFL_WQLT_TN', 'INFL_ASSCT_BFR_WQLT_TP', 'EFFL_WQLT_TP', 'TP_INFL_WQLT_TP', 'EFFL_WQLT_TP'];
const txtArray = ['1', 'INFL_AMNT', 'SUM_FLOW', 'RETURN_AMNT', 'EFFL_AMNT', 'INFL_ASSCT_BFR_WQLT_BOD', 'EFFL_WQLT_BOD', 'INFL_ASSCT_BFR_WQLT_TN', 'EFFL_WQLT_TN', 'INFL_ASSCT_BFR_WQLT_TP', 'EFFL_WQLT_TP', 'INFL_ASSCT_BFR_WQLT_TP', 'EFFL_WQLT_TP'];
if(operationalStatusList[i]){
if(i < 7){
changeValue(operationalStatusList[i], data, txtArray[i]);
@@ -1269,8 +1106,8 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
시군구: item.sggNm,
주소: item.addr,
용량: item.fctCpc,
유입BOD: item.inflAssctBfrWqltBod,
유입TN: item.inflAssctBfrWqltTn,
유입BOD: item.inflAssctAftWqltBod,
유입TN: item.inflAssctAftWqltTn,
유입TP: item.inflAssctBfrWqltTp,
유출BOD: item.efflWqltBod,
유출TN: item.efflWqltTn,
@@ -1290,20 +1127,12 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
OperationStatus: {
...state.OperationStatus,
operationalStatusList: operationalStatusList,
operationalStatusCount: res.count,
isLoadingOperationStatus : false,
},
operationalStatusCount: res.count
}
}))
},
searchMainGraph: async (searchYear: string, fcltyCd: string) => {
set((state: DashBoardType) => ({
...state,
MainGraph: {
...state.MainGraph,
isLoadingMainGraph: true,
},
}));
const res = await fetchMainGraph(searchYear, fcltyCd);
if(res == null || res.data == null || res.data.length === 0) {
set((state: DashBoardType) => ({
@@ -1319,7 +1148,6 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
chart_efflTn: [],
chart_inflBod: [],
chart_efflBod: [],
isLoadingMainGraph : false,
}
}));
return;
@@ -1335,7 +1163,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
const chart_bodRain = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
label: item.msrDt.substring(0, 4)+"-"+item.msrDt.substring(4, 6)+"-"+item.msrDt.substring(6, 8),
barVal0: item.infoRnDay ?? 0,
lineVal0: item.inflAssctBfrWqltBod ?? 0,
lineVal0: item.inflAssctAftWqltBod ?? 0,
}));
const chart_inflTp = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
@@ -1355,7 +1183,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
const chart_inflTn = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
label: item.msrDt.substring(0, 4)+"-"+item.msrDt.substring(4, 6)+"-"+item.msrDt.substring(6, 8),
val : item.inflAssctBfrWqltTn ?? 0
val : item.inflAssctAftWqltTn ?? 0
}));
const chart_efflTn = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
@@ -1365,7 +1193,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
const chart_inflBod = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
label: item.msrDt.substring(0, 4)+"-"+item.msrDt.substring(4, 6)+"-"+item.msrDt.substring(6, 8),
val : item.inflAssctBfrWqltBod ?? 0
val : item.inflAssctAftWqltBod ?? 0
}));
const chart_efflBod = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({
@@ -1385,20 +1213,12 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
chart_inflTn: chart_inflTn,
chart_efflTn: chart_efflTn,
chart_inflBod: chart_inflBod,
chart_efflBod: chart_efflBod,
isLoadingMainGraph : false,
},
chart_efflBod: chart_efflBod
}
}))
},
searchRainManage: async (searchYear: string, fcltyCd: string, isExcel : boolean) => {
set((state: DashBoardType) => ({
...state,
RainManage: {
...state.RainManage,
isLoadingRainManage: true,
},
}));
const res = await fetchMainGraph(searchYear, fcltyCd);
if(res == null || res.data.wqltObjs == null || res.data.wqltObjs.length === 0) {
set((state: DashBoardType) => ({
@@ -1406,7 +1226,6 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
RainManage: {
...state.RainManage,
rainManageList: [],
isLoadingRainManage : false,
}
}));
return;
@@ -1424,51 +1243,75 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
const dsInflWqltSs: number[] = [0, 0, 0, 0, 0, 0, 0, 0];
const dsInflWqltTn: number[] = [0, 0, 0, 0, 0, 0, 0, 0];
const dsInflWqltTp: number[] = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltBodCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltBod = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltTocCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltToc = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltSsCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltSs = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltTnCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltTn = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltTpCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctBfrWqltTp = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltBodCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltBod = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltTocCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltToc = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltSsCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltSs = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltTnCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltTn = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltTpCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const inflAssctAftWqltTp = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltBodCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltBod = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltTocCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltToc = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltCodCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltCod = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltSsCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltSs = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltTnCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltTn = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltTpCnt = [0, 0, 0, 0, 0, 0, 0, 0];
const efflWqltTp = [0, 0, 0, 0, 0, 0, 0, 0];
// 청천시 중 강우영향일인 날짜는 이전의 강우량을 대입해 리스트 수정
const rainEffectList = calRainEffectDayRainManage(res.data.wqltObjs);
// Process the data and create rain management list
rainEffectList.forEach((item: RainManageListProps) => {
res.data.wqltObjs.forEach((item: RainManageListProps) => {
// 강우일
/*if(Number(item.infoRnDay) < 3){
rainDate[1] = Number(rainDate[1] || 0) + 1;
inflAmtCnt[1] = Number(inflAmtCnt[1] || 0) + 1;
inflAmnt[1] = Number(inflAmnt[1] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[1] = 0;
inflAssctAftWqltBodCnt[1] = Number(inflAssctAftWqltBodCnt[1] || 0) + 1;
inflAssctAftWqltBod[1] = Number(inflAssctAftWqltBod[1] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[1] = Number(inflAssctAftWqltTocCnt[1] || 0) + 1;
inflAssctAftWqltToc[1] = Number(inflAssctAftWqltToc[1] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[1] = Number(inflAssctAftWqltSsCnt[1] || 0) + 1;
inflAssctAftWqltSs[1] = Number(inflAssctAftWqltSs[1] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[1] = Number(inflAssctAftWqltTnCnt[1] || 0) + 1;
inflAssctAftWqltTn[1] = Number(inflAssctAftWqltTn[1] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[1] = Number(inflAssctAftWqltTpCnt[1] || 0) + 1;
inflAssctAftWqltTp[1] = Number(inflAssctAftWqltTp[1] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[1] = Number(efflWqltBodCnt[1] || 0) + 1;
efflWqltBod[1] = Number(efflWqltBod[1] || 0) + Number(item.efflWqltBod || 0);
efflWqltCodCnt[1] = Number(efflWqltCodCnt[1] || 0) + 1;
efflWqltCod[1] = Number(efflWqltCod[1] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[1] = Number(efflWqltSsCnt[1] || 0) + 1;
efflWqltSs[1] = Number(efflWqltSs[1] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[1] = Number(efflWqltTnCnt[1] || 0) + 1;
efflWqltTn[1] = Number(efflWqltTn[1] || 0) + Number(item.efflWqltTn || 0);
efflWqltTpCnt[1] = Number(efflWqltTpCnt[1] || 0) + 1;
efflWqltTp[1] = Number(efflWqltTp[1] || 0) + Number(item.efflWqltTp || 0);
}*/
if(Number(item.infoRnDay) >= 3 && Number(item.infoRnDay) < 10){
rainDate[1] = Number(rainDate[1] || 0) + 1;
inflAmtCnt[1] = Number(inflAmtCnt[1] || 0) + 1;
inflAmnt[1] = Number(inflAmnt[1] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[1] = 0;
inflAssctBfrWqltBodCnt[1] = Number(inflAssctBfrWqltBodCnt[1] || 0) + 1;
inflAssctBfrWqltBod[1] = Number(inflAssctBfrWqltBod[1] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[1] = Number(inflAssctBfrWqltTocCnt[1] || 0) + 1;
inflAssctBfrWqltToc[1] = Number(inflAssctBfrWqltToc[1] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[1] = Number(inflAssctBfrWqltSsCnt[1] || 0) + 1;
inflAssctBfrWqltSs[1] = Number(inflAssctBfrWqltSs[1] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[1] = Number(inflAssctBfrWqltTnCnt[1] || 0) + 1;
inflAssctBfrWqltTn[1] = Number(inflAssctBfrWqltTn[1] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[1] = Number(inflAssctBfrWqltTpCnt[1] || 0) + 1;
inflAssctBfrWqltTp[1] = Number(inflAssctBfrWqltTp[1] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[1] = Number(inflAssctAftWqltBodCnt[1] || 0) + 1;
inflAssctAftWqltBod[1] = Number(inflAssctAftWqltBod[1] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[1] = Number(inflAssctAftWqltTocCnt[1] || 0) + 1;
inflAssctAftWqltToc[1] = Number(inflAssctAftWqltToc[1] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[1] = Number(inflAssctAftWqltSsCnt[1] || 0) + 1;
inflAssctAftWqltSs[1] = Number(inflAssctAftWqltSs[1] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[1] = Number(inflAssctAftWqltTnCnt[1] || 0) + 1;
inflAssctAftWqltTn[1] = Number(inflAssctAftWqltTn[1] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[1] = Number(inflAssctAftWqltTpCnt[1] || 0) + 1;
inflAssctAftWqltTp[1] = Number(inflAssctAftWqltTp[1] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[1] = Number(efflWqltBodCnt[1] || 0) + 1;
efflWqltBod[1] = Number(efflWqltBod[1] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[1] = Number(efflWqltTocCnt[1] || 0) + 1;
efflWqltToc[1] = Number(efflWqltToc[1] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[1] = Number(efflWqltCodCnt[1] || 0) + 1;
efflWqltCod[1] = Number(efflWqltCod[1] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[1] = Number(efflWqltSsCnt[1] || 0) + 1;
efflWqltSs[1] = Number(efflWqltSs[1] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[1] = Number(efflWqltTnCnt[1] || 0) + 1;
@@ -1480,20 +1323,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[2] = Number(inflAmtCnt[2] || 0) + 1;
inflAmnt[2] = Number(inflAmnt[2] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[2] = 0;
inflAssctBfrWqltBodCnt[2] = Number(inflAssctBfrWqltBodCnt[2] || 0) + 1;
inflAssctBfrWqltBod[2] = Number(inflAssctBfrWqltBod[2] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[2] = Number(inflAssctBfrWqltTocCnt[2] || 0) + 1;
inflAssctBfrWqltToc[2] = Number(inflAssctBfrWqltToc[2] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[2] = Number(inflAssctBfrWqltSsCnt[2] || 0) + 1;
inflAssctBfrWqltSs[2] = Number(inflAssctBfrWqltSs[2] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[2] = Number(inflAssctBfrWqltTnCnt[2] || 0) + 1;
inflAssctBfrWqltTn[2] = Number(inflAssctBfrWqltTn[2] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[2] = Number(inflAssctBfrWqltTpCnt[2] || 0) + 1;
inflAssctBfrWqltTp[2] = Number(inflAssctBfrWqltTp[2] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[2] = Number(inflAssctAftWqltBodCnt[2] || 0) + 1;
inflAssctAftWqltBod[2] = Number(inflAssctAftWqltBod[2] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[2] = Number(inflAssctAftWqltTocCnt[2] || 0) + 1;
inflAssctAftWqltToc[2] = Number(inflAssctAftWqltToc[2] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[2] = Number(inflAssctAftWqltSsCnt[2] || 0) + 1;
inflAssctAftWqltSs[2] = Number(inflAssctAftWqltSs[2] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[2] = Number(inflAssctAftWqltTnCnt[2] || 0) + 1;
inflAssctAftWqltTn[2] = Number(inflAssctAftWqltTn[2] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[2] = Number(inflAssctAftWqltTpCnt[2] || 0) + 1;
inflAssctAftWqltTp[2] = Number(inflAssctAftWqltTp[2] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[2] = Number(efflWqltBodCnt[2] || 0) + 1;
efflWqltBod[2] = Number(efflWqltBod[2] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[2] = Number(efflWqltTocCnt[2] || 0) + 1;
efflWqltToc[2] = Number(efflWqltToc[2] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[2] = Number(efflWqltCodCnt[2] || 0) + 1;
efflWqltCod[2] = Number(efflWqltCod[2] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[2] = Number(efflWqltSsCnt[2] || 0) + 1;
efflWqltSs[2] = Number(efflWqltSs[2] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[2] = Number(efflWqltTnCnt[2] || 0) + 1;
@@ -1505,20 +1348,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[3] = Number(inflAmtCnt[3] || 0) + 1;
inflAmnt[3] = Number(inflAmnt[3] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[3] = 0;
inflAssctBfrWqltBodCnt[3] = Number(inflAssctBfrWqltBodCnt[3] || 0) + 1;
inflAssctBfrWqltBod[3] = Number(inflAssctBfrWqltBod[3] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[3] = Number(inflAssctBfrWqltTocCnt[3] || 0) + 1;
inflAssctBfrWqltToc[3] = Number(inflAssctBfrWqltToc[3] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[3] = Number(inflAssctBfrWqltSsCnt[3] || 0) + 1;
inflAssctBfrWqltSs[3] = Number(inflAssctBfrWqltSs[3] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[3] = Number(inflAssctBfrWqltTnCnt[3] || 0) + 1;
inflAssctBfrWqltTn[3] = Number(inflAssctBfrWqltTn[3] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[3] = Number(inflAssctBfrWqltTpCnt[3] || 0) + 1;
inflAssctBfrWqltTp[3] = Number(inflAssctBfrWqltTp[3] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[3] = Number(inflAssctAftWqltBodCnt[3] || 0) + 1;
inflAssctAftWqltBod[3] = Number(inflAssctAftWqltBod[3] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[3] = Number(inflAssctAftWqltTocCnt[3] || 0) + 1;
inflAssctAftWqltToc[3] = Number(inflAssctAftWqltToc[3] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[3] = Number(inflAssctAftWqltSsCnt[3] || 0) + 1;
inflAssctAftWqltSs[3] = Number(inflAssctAftWqltSs[3] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[3] = Number(inflAssctAftWqltTnCnt[3] || 0) + 1;
inflAssctAftWqltTn[3] = Number(inflAssctAftWqltTn[3] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[3] = Number(inflAssctAftWqltTpCnt[3] || 0) + 1;
inflAssctAftWqltTp[3] = Number(inflAssctAftWqltTp[3] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[3] = Number(efflWqltBodCnt[3] || 0) + 1;
efflWqltBod[3] = Number(efflWqltBod[3] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[3] = Number(efflWqltTocCnt[3] || 0) + 1;
efflWqltToc[3] = Number(efflWqltToc[3] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[3] = Number(efflWqltCodCnt[3] || 0) + 1;
efflWqltCod[3] = Number(efflWqltCod[3] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[3] = Number(efflWqltSsCnt[3] || 0) + 1;
efflWqltSs[3] = Number(efflWqltSs[3] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[3] = Number(efflWqltTnCnt[3] || 0) + 1;
@@ -1530,20 +1373,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[4] = Number(inflAmtCnt[4] || 0) + 1;
inflAmnt[4] = Number(inflAmnt[4] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[4] = item.inflAmnt&&Number(item.inflAmnt) !== 0 ? Number(Math.round(Number(item.inflAmnt) / Number(item.fctCpc) * 10) / 10) : 0;
inflAssctBfrWqltBodCnt[4] = Number(inflAssctBfrWqltBodCnt[4] || 0) + 1;
inflAssctBfrWqltBod[4] = Number(inflAssctBfrWqltBod[4] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[4] = Number(inflAssctBfrWqltTocCnt[4] || 0) + 1;
inflAssctBfrWqltToc[4] = Number(inflAssctBfrWqltToc[4] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[4] = Number(inflAssctBfrWqltSsCnt[4] || 0) + 1;
inflAssctBfrWqltSs[4] = Number(inflAssctBfrWqltSs[4] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[4] = Number(inflAssctBfrWqltTnCnt[4] || 0) + 1;
inflAssctBfrWqltTn[4] = Number(inflAssctBfrWqltTn[5] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[4] = Number(inflAssctBfrWqltTpCnt[4] || 0) + 1;
inflAssctBfrWqltTp[4] = Number(inflAssctBfrWqltTp[4] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[4] = Number(inflAssctAftWqltBodCnt[4] || 0) + 1;
inflAssctAftWqltBod[4] = Number(inflAssctAftWqltBod[4] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[4] = Number(inflAssctAftWqltTocCnt[4] || 0) + 1;
inflAssctAftWqltToc[4] = Number(inflAssctAftWqltToc[4] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[4] = Number(inflAssctAftWqltSsCnt[4] || 0) + 1;
inflAssctAftWqltSs[4] = Number(inflAssctAftWqltSs[4] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[4] = Number(inflAssctAftWqltTnCnt[4] || 0) + 1;
inflAssctAftWqltTn[4] = Number(inflAssctAftWqltTn[5] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[4] = Number(inflAssctAftWqltTpCnt[4] || 0) + 1;
inflAssctAftWqltTp[4] = Number(inflAssctAftWqltTp[4] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[4] = Number(efflWqltBodCnt[4] || 0) + 1;
efflWqltBod[4] = Number(efflWqltBod[4] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[4] = Number(efflWqltTocCnt[4] || 0) + 1;
efflWqltToc[4] = Number(efflWqltToc[4] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[4] = Number(efflWqltCodCnt[4] || 0) + 1;
efflWqltCod[4] = Number(efflWqltCod[4] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[4] = Number(efflWqltSsCnt[4] || 0) + 1;
efflWqltSs[4] = Number(efflWqltSs[4] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[4] = Number(efflWqltTnCnt[5] || 0) + 1;
@@ -1555,20 +1398,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[5] = Number(inflAmtCnt[5] || 0) + 1;
inflAmnt[5] = Number(inflAmnt[5] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[5] = 0;
inflAssctBfrWqltBodCnt[5] = Number(inflAssctBfrWqltBodCnt[5] || 0) + 1;
inflAssctBfrWqltBod[5] = Number(inflAssctBfrWqltBod[5] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[5] = Number(inflAssctBfrWqltTocCnt[5] || 0) + 1;
inflAssctBfrWqltToc[5] = Number(inflAssctBfrWqltToc[5] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[5] = Number(inflAssctBfrWqltSsCnt[5] || 0) + 1;
inflAssctBfrWqltSs[5] = Number(inflAssctBfrWqltSs[5] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[5] = Number(inflAssctBfrWqltTnCnt[5] || 0) + 1;
inflAssctBfrWqltTn[5] = Number(inflAssctBfrWqltTn[5] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[5] = Number(inflAssctBfrWqltTpCnt[5] || 0) + 1;
inflAssctBfrWqltTp[5] = Number(inflAssctBfrWqltTp[5] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[5] = Number(inflAssctAftWqltBodCnt[5] || 0) + 1;
inflAssctAftWqltBod[5] = Number(inflAssctAftWqltBod[5] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[5] = Number(inflAssctAftWqltTocCnt[5] || 0) + 1;
inflAssctAftWqltToc[5] = Number(inflAssctAftWqltToc[5] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[5] = Number(inflAssctAftWqltSsCnt[5] || 0) + 1;
inflAssctAftWqltSs[5] = Number(inflAssctAftWqltSs[5] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[5] = Number(inflAssctAftWqltTnCnt[5] || 0) + 1;
inflAssctAftWqltTn[5] = Number(inflAssctAftWqltTn[5] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[5] = Number(inflAssctAftWqltTpCnt[5] || 0) + 1;
inflAssctAftWqltTp[5] = Number(inflAssctAftWqltTp[5] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[5] = Number(efflWqltBodCnt[5] || 0) + 1;
efflWqltBod[5] = Number(efflWqltBod[5] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[5] = Number(efflWqltTocCnt[5] || 0) + 1;
efflWqltToc[5] = Number(efflWqltToc[5] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[5] = Number(efflWqltCodCnt[5] || 0) + 1;
efflWqltCod[5] = Number(efflWqltCod[5] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[5] = Number(efflWqltSsCnt[5] || 0) + 1;
efflWqltSs[5] = Number(efflWqltSs[5] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[5] = Number(efflWqltTnCnt[5] || 0) + 1;
@@ -1580,20 +1423,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[6] = Number(inflAmtCnt[6] || 0) + 1;
inflAmnt[6] = Number(inflAmnt[6] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[6] = 0;
inflAssctBfrWqltBodCnt[6] = Number(inflAssctBfrWqltBodCnt[6] || 0) + 1;
inflAssctBfrWqltBod[6] = Number(inflAssctBfrWqltBod[6] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[6] = Number(inflAssctBfrWqltTocCnt[6] || 0) + 1;
inflAssctBfrWqltToc[6] = Number(inflAssctBfrWqltToc[6] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[6] = Number(inflAssctBfrWqltSsCnt[6] || 0) + 1;
inflAssctBfrWqltSs[6] = Number(inflAssctBfrWqltSs[6] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[6] = Number(inflAssctBfrWqltTnCnt[6] || 0) + 1;
inflAssctBfrWqltTn[6] = Number(inflAssctBfrWqltTn[6] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[6] = Number(inflAssctBfrWqltTpCnt[6] || 0) + 1;
inflAssctBfrWqltTp[6] = Number(inflAssctBfrWqltTp[6] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[6] = Number(inflAssctAftWqltBodCnt[6] || 0) + 1;
inflAssctAftWqltBod[6] = Number(inflAssctAftWqltBod[6] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[6] = Number(inflAssctAftWqltTocCnt[6] || 0) + 1;
inflAssctAftWqltToc[6] = Number(inflAssctAftWqltToc[6] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[6] = Number(inflAssctAftWqltSsCnt[6] || 0) + 1;
inflAssctAftWqltSs[6] = Number(inflAssctAftWqltSs[6] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[6] = Number(inflAssctAftWqltTnCnt[6] || 0) + 1;
inflAssctAftWqltTn[6] = Number(inflAssctAftWqltTn[6] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[6] = Number(inflAssctAftWqltTpCnt[6] || 0) + 1;
inflAssctAftWqltTp[6] = Number(inflAssctAftWqltTp[6] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[6] = Number(efflWqltBodCnt[6] || 0) + 1;
efflWqltBod[6] = Number(efflWqltBod[6] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[6] = Number(efflWqltTocCnt[6] || 0) + 1;
efflWqltToc[6] = Number(efflWqltToc[6] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[6] = Number(efflWqltCodCnt[6] || 0) + 1;
efflWqltCod[6] = Number(efflWqltCod[6] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[6] = Number(efflWqltSsCnt[6] || 0) + 1;
efflWqltSs[6] = Number(efflWqltSs[6] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[6] = Number(efflWqltTnCnt[6] || 0) + 1;
@@ -1605,20 +1448,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmtCnt[7] = Number(inflAmtCnt[7] || 0) + 1;
inflAmnt[7] = Number(inflAmnt[7] || 0) + Number(item.inflAmnt || 0);
fcltyCpct[7] = 0;
inflAssctBfrWqltBodCnt[7] = Number(inflAssctBfrWqltBodCnt[7] || 0) + 1;
inflAssctBfrWqltBod[7] = Number(inflAssctBfrWqltBod[7] || 0) + Number(item.inflAssctBfrWqltBod || 0);
inflAssctBfrWqltTocCnt[7] = Number(inflAssctBfrWqltTocCnt[7] || 0) + 1;
inflAssctBfrWqltToc[7] = Number(inflAssctBfrWqltToc[7] || 0) + Number(item.inflAssctBfrWqltToc || 0);
inflAssctBfrWqltSsCnt[7] = Number(inflAssctBfrWqltSsCnt[7] || 0) + 1;
inflAssctBfrWqltSs[7] = Number(inflAssctBfrWqltSs[7] || 0) + Number(item.inflAssctBfrWqltSs || 0);
inflAssctBfrWqltTnCnt[7] = Number(inflAssctBfrWqltTnCnt[7] || 0) + 1;
inflAssctBfrWqltTn[7] = Number(inflAssctBfrWqltTn[7] || 0) + Number(item.inflAssctBfrWqltTn || 0);
inflAssctBfrWqltTpCnt[7] = Number(inflAssctBfrWqltTpCnt[7] || 0) + 1;
inflAssctBfrWqltTp[7] = Number(inflAssctBfrWqltTp[7] || 0) + Number(item.inflAssctBfrWqltTp || 0);
inflAssctAftWqltBodCnt[7] = Number(inflAssctAftWqltBodCnt[7] || 0) + 1;
inflAssctAftWqltBod[7] = Number(inflAssctAftWqltBod[7] || 0) + Number(item.inflAssctAftWqltBod || 0);
inflAssctAftWqltTocCnt[7] = Number(inflAssctAftWqltTocCnt[7] || 0) + 1;
inflAssctAftWqltToc[7] = Number(inflAssctAftWqltToc[7] || 0) + Number(item.inflAssctAftWqltToc || 0);
inflAssctAftWqltSsCnt[7] = Number(inflAssctAftWqltSsCnt[7] || 0) + 1;
inflAssctAftWqltSs[7] = Number(inflAssctAftWqltSs[7] || 0) + Number(item.inflAssctAftWqltSs || 0);
inflAssctAftWqltTnCnt[7] = Number(inflAssctAftWqltTnCnt[7] || 0) + 1;
inflAssctAftWqltTn[7] = Number(inflAssctAftWqltTn[7] || 0) + Number(item.inflAssctAftWqltTn || 0);
inflAssctAftWqltTpCnt[7] = Number(inflAssctAftWqltTpCnt[7] || 0) + 1;
inflAssctAftWqltTp[7] = Number(inflAssctAftWqltTp[7] || 0) + Number(item.inflAssctAftWqltTp || 0);
efflWqltBodCnt[7] = Number(efflWqltBodCnt[7] || 0) + 1;
efflWqltBod[7] = Number(efflWqltBod[7] || 0) + Number(item.efflWqltBod || 0);
efflWqltTocCnt[7] = Number(efflWqltTocCnt[7] || 0) + 1;
efflWqltToc[7] = Number(efflWqltToc[7] || 0) + Number(item.efflWqltToc || 0);
efflWqltCodCnt[7] = Number(efflWqltCodCnt[7] || 0) + 1;
efflWqltCod[7] = Number(efflWqltCod[7] || 0) + Number(item.efflWqltCod || 0);
efflWqltSsCnt[7] = Number(efflWqltSsCnt[7] || 0) + 1;
efflWqltSs[7] = Number(efflWqltSs[7] || 0) + Number(item.efflWqltSs || 0);
efflWqltTnCnt[7] = Number(efflWqltTnCnt[7] || 0) + 1;
@@ -1696,13 +1539,13 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
for(let idx=0; idx<inflAmnt.length; idx++){
inflAmnt[idx] = calculateAverage(Number(inflAmnt[idx]), Number(inflAmtCnt[idx]));
inflAssctBfrWqltBod[idx] = calculateAverage(Number(inflAssctBfrWqltBod[idx]), Number(inflAssctBfrWqltBodCnt[idx]));
inflAssctBfrWqltToc[idx] = calculateAverage(Number(inflAssctBfrWqltToc[idx]), Number(inflAssctBfrWqltTocCnt[idx]));
inflAssctBfrWqltSs[idx] = calculateAverage(Number(inflAssctBfrWqltSs[idx]), Number(inflAssctBfrWqltSsCnt[idx]));
inflAssctBfrWqltTn[idx] = calculateAverage(Number(inflAssctBfrWqltTn[idx]), Number(inflAssctBfrWqltTnCnt[idx]));
inflAssctBfrWqltTp[idx] = calculateAverage(Number(inflAssctBfrWqltTp[idx]), Number(inflAssctBfrWqltTpCnt[idx]));
inflAssctAftWqltBod[idx] = calculateAverage(Number(inflAssctAftWqltBod[idx]), Number(inflAssctAftWqltBodCnt[idx]));
inflAssctAftWqltToc[idx] = calculateAverage(Number(inflAssctAftWqltToc[idx]), Number(inflAssctAftWqltTocCnt[idx]));
inflAssctAftWqltSs[idx] = calculateAverage(Number(inflAssctAftWqltSs[idx]), Number(inflAssctAftWqltSsCnt[idx]));
inflAssctAftWqltTn[idx] = calculateAverage(Number(inflAssctAftWqltTn[idx]), Number(inflAssctAftWqltTnCnt[idx]));
inflAssctAftWqltTp[idx] = calculateAverage(Number(inflAssctAftWqltTp[idx]), Number(inflAssctAftWqltTpCnt[idx]));
efflWqltBod[idx] = calculateAverage(Number(efflWqltBod[idx]), Number(efflWqltBodCnt[idx]));
efflWqltToc[idx] = calculateAverage(Number(efflWqltToc[idx]), Number(efflWqltTocCnt[idx]));
efflWqltCod[idx] = calculateAverage(Number(efflWqltCod[idx]), Number(efflWqltCodCnt[idx]));
efflWqltSs[idx] = calculateAverage(Number(efflWqltSs[idx]), Number(efflWqltSsCnt[idx]));
efflWqltTn[idx] = calculateAverage(Number(efflWqltTn[idx]), Number(efflWqltTnCnt[idx]));
efflWqltTp[idx] = calculateAverage(Number(efflWqltTp[idx]), Number(efflWqltTpCnt[idx]));
@@ -1715,13 +1558,13 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
inflAmnt[0] = calculateAverage(calculateTotal(inflAmnt), dataIsCount);
fcltyCpct[0] = calculateTotal(fcltyCpct);
inflAssctBfrWqltBod[0] = Number((calculateTotal(inflAssctBfrWqltBod)/7).toFixed(1));
inflAssctBfrWqltToc[0] = Number((calculateTotal(inflAssctBfrWqltToc)/7).toFixed(1));
inflAssctBfrWqltSs[0] = Number((calculateTotal(inflAssctBfrWqltSs)/7).toFixed(1));
inflAssctBfrWqltTn[0] = Number((calculateTotal(inflAssctBfrWqltTn)/7).toFixed(3));
inflAssctBfrWqltTp[0] = Number((calculateTotal(inflAssctBfrWqltTp)/7).toFixed(3));
inflAssctAftWqltBod[0] = Number((calculateTotal(inflAssctAftWqltBod)/7).toFixed(1));
inflAssctAftWqltToc[0] = Number((calculateTotal(inflAssctAftWqltToc)/7).toFixed(1));
inflAssctAftWqltSs[0] = Number((calculateTotal(inflAssctAftWqltSs)/7).toFixed(1));
inflAssctAftWqltTn[0] = Number((calculateTotal(inflAssctAftWqltTn)/7).toFixed(3));
inflAssctAftWqltTp[0] = Number((calculateTotal(inflAssctAftWqltTp)/7).toFixed(3));
efflWqltBod[0] = Number((calculateTotal(efflWqltBod)/7).toFixed(1));
efflWqltToc[0] = Number((calculateTotal(efflWqltToc)/7).toFixed(1));
efflWqltCod[0] = Number((calculateTotal(efflWqltCod)/7).toFixed(1));
efflWqltSs[0] = Number((calculateTotal(efflWqltSs as number[])/7).toFixed(1));
efflWqltTn[0] = Number((calculateTotal(efflWqltTn as number[])/7).toFixed(3));
efflWqltTp[0] = Number((calculateTotal(efflWqltTp as number[])/7).toFixed(3));
@@ -1738,13 +1581,13 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
dsInflWqltSs: dsInflWqltSs[index] ? Number(dsInflWqltSs[index].toFixed(1)) : '',
dsInflWqltTn: dsInflWqltTn[index] ? dsInflWqltTn[index].toFixed(3) : '',
dsInflWqltTp: dsInflWqltTp[index] ? dsInflWqltTp[index].toFixed(3) : '',
inflAssctBfrWqltBod: inflAssctBfrWqltBod[index] ? Number(inflAssctBfrWqltBod[index].toFixed(1)) : '',
inflAssctBfrWqltToc: inflAssctBfrWqltToc[index] ? Number(inflAssctBfrWqltToc[index].toFixed(1)) : '',
inflAssctBfrWqltSs: inflAssctBfrWqltSs[index] ? Number(inflAssctBfrWqltSs[index].toFixed(1)) : '',
inflAssctBfrWqltTn: inflAssctBfrWqltTn[index] ? inflAssctBfrWqltTn[index].toFixed(3) : '',
inflAssctBfrWqltTp: inflAssctBfrWqltTp[index] ? inflAssctBfrWqltTp[index].toFixed(3) : '',
inflAssctAftWqltBod: inflAssctAftWqltBod[index] ? Number(inflAssctAftWqltBod[index].toFixed(1)) : '',
inflAssctAftWqltToc: inflAssctAftWqltToc[index] ? Number(inflAssctAftWqltToc[index].toFixed(1)) : '',
inflAssctAftWqltSs: inflAssctAftWqltSs[index] ? Number(inflAssctAftWqltSs[index].toFixed(1)) : '',
inflAssctAftWqltTn: inflAssctAftWqltTn[index] ? inflAssctAftWqltTn[index].toFixed(3) : '',
inflAssctAftWqltTp: inflAssctAftWqltTp[index] ? inflAssctAftWqltTp[index].toFixed(3) : '',
efflWqltBod: efflWqltBod[index] ? Number(efflWqltBod[index].toFixed(1)) : '',
efflWqltToc: efflWqltToc[index] ? Number(efflWqltToc[index].toFixed(1)) : '',
efflWqltCod: efflWqltCod[index] ? Number(efflWqltCod[index].toFixed(1)) : '',
efflWqltSs: efflWqltSs[index] ? Number(efflWqltSs[index].toFixed(1)) : '',
efflWqltTn: efflWqltTn[index] ? efflWqltTn[index].toFixed(3) : '',
efflWqltTp: efflWqltTp[index] ? efflWqltTp[index].toFixed(3) : ''
@@ -1764,13 +1607,13 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
설계유입수질SS: item.dsInflWqltSs ? Number(Number(item.dsInflWqltSs).toFixed(1)) : '',
설계유입수질TN: item.dsInflWqltTn ? Number(item.dsInflWqltTn).toFixed(3) : '',
설계유입수질TP: item.dsInflWqltTp ? Number(item.dsInflWqltTp).toFixed(3) : '',
유입수질BOD: item.inflAssctBfrWqltBod ? Number(Number(item.inflAssctBfrWqltBod).toFixed(1)) : '',
유입수질TOC: item.inflAssctBfrWqltToc ? Number(Number(item.inflAssctBfrWqltToc).toFixed(1)) : '',
유입수질SS: item.inflAssctBfrWqltSs ? Number(Number(item.inflAssctBfrWqltSs).toFixed(1)) : '',
유입수질TN: item.inflAssctBfrWqltTn ? Number(item.inflAssctBfrWqltTn).toFixed(3) : '',
유입수질TP: item.inflAssctBfrWqltTp ? Number(item.inflAssctBfrWqltTp).toFixed(3) : '',
유입수질BOD: item.inflAssctAftWqltBod ? Number(Number(item.inflAssctAftWqltBod).toFixed(1)) : '',
유입수질TOC: item.inflAssctAftWqltToc ? Number(Number(item.inflAssctAftWqltToc).toFixed(1)) : '',
유입수질SS: item.inflAssctAftWqltSs ? Number(Number(item.inflAssctAftWqltSs).toFixed(1)) : '',
유입수질TN: item.inflAssctAftWqltTn ? Number(item.inflAssctAftWqltTn).toFixed(3) : '',
유입수질TP: item.inflAssctAftWqltTp ? Number(item.inflAssctAftWqltTp).toFixed(3) : '',
방류수질BOD: item.efflWqltBod ? Number(Number(item.efflWqltBod).toFixed(1)) : '',
방류수질TOC: item.efflWqltToc ? Number(Number(item.efflWqltToc).toFixed(1)) : '',
방류수질TOC: item.efflWqltCod ? Number(Number(item.efflWqltCod).toFixed(1)) : '',
방류수질SS: item.efflWqltSs ? Number(Number(item.efflWqltSs).toFixed(1)) : '',
방류수질TN: item.efflWqltTn ? Number(item.efflWqltTn).toFixed(3) : '',
방류수질TP: item.efflWqltTp ? Number(item.efflWqltTp).toFixed(3) : '',
@@ -1784,13 +1627,61 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
...state.RainManage,
rainManageList: filteredData as RainManageListProps[],
excelList: excelList,
isLoadingRainManage : false,
} : {
...state.RainManage,
rainManageList: filteredData as RainManageListProps[],
isLoadingRainManage : false,
}
}));
},
searchDrainageEquipment: async (searchYear: string, fcltyCd: string, isExcel : boolean) => {
await fetchDrainageEquipment(searchYear, fcltyCd);
/* if(res == null || res.data.wqltObjs == null || res.data.wqltObjs.length === 0) {
set((state: DashBoardType) => ({
...state.RainManage,
rainManageList: [],
}));
return;
} */
/* if(isExcel){
res.data.wqltObjs.forEach((item) => {
excelList.push({
강우량: item.rainItem,
강우조건비율: item.rainRate || 0,
일수: item.rainDay || 0,
유입유량: item.inflAmnt || 0,
시설용량대비: item.fctCpc || 0,
설계유입수질BOD: item.dsInflWqltBod || 0,
설계유입수질TOC: item.dsInflWqltCod || 0,
설계유입수질SS: item.dsInflWqltSs || 0,
설계유입수질TN: item.dsInflWqltTn || 0,
설계유입수질TP: item.dsInflWqltTp || 0,
유입수질BOD: item.inflAssctAftWqltBod || 0,
유입수질COD: item.inflAssctAftWqltToc || 0,
유입수질SS: item.inflAssctAftWqltSs || 0,
유입수질TN: item.inflAssctAftWqltTn || 0,
유입수질TP: item.inflAssctAftWqltTp || 0,
방류수질BOD: item.efflWqltBod || 0,
방류수질COD: item.efflWqltCod || 0,
방류수질SS: item.efflWqltSs || 0,
방류수질TN: item.efflWqltTn || 0,
방류수질TP: item.efflWqltTp || 0,
});
});
} */
set((state: DashBoardType) => ({
...state,
DrainageEquipment: isExcel ? {
...state.DrainageEquipment,
drainageEquipmentList: drainageEquipmentList,
drainageEquipmentExcelList: [],
} : {
...state.DrainageEquipment,
drainageEquipmentList: drainageEquipmentList,
}
}));
}
}
}
@@ -217,7 +217,6 @@ export type FacilityPrecipitationType = {
facilityPrecipitation: FacilityPrecipitationProps[];
excelList: ExcelType[];
facilityPrecipitationCount: number;
isLoading: boolean;
},
PrecipitationDetail : {
@@ -240,8 +239,7 @@ export const facilityPrecipitationInitState: FacilityPrecipitationType = {
upHeadList3 : upHeadList3,
facilityPrecipitation : facilityPrecipitation,
excelList : [],
facilityPrecipitationCount : 0,
isLoading : true,
facilityPrecipitationCount : 0
},
PrecipitationDetail : {
@@ -256,14 +254,6 @@ export type FacilityPrecipitationStore = FacilityPrecipitationType & FacilityPre
export const facilityPrecipitationReducer:(set:(fn: (state: FacilityPrecipitationType) => FacilityPrecipitationType) => void)=>FacilityPrecipitationActions=(set: (fn: (state: FacilityPrecipitationType) => FacilityPrecipitationType) => void) => {
return {
searchFacilityPrecipitationList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FacilityPrecipitationType) => ({
...state,
FacilityPrecipitation: {
...state.FacilityPrecipitation,
isLoading: true,
},
}));
const res = await fetchFacilityPrecipitationList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
const excelDownList: ExcelType[] = [];
@@ -303,15 +293,13 @@ export const facilityPrecipitationReducer:(set:(fn: (state: FacilityPrecipitatio
...state.FacilityPrecipitation,
facilityPrecipitation: res.data,
facilityPrecipitationCount: res.count,
isLoading : false,
}:{
...state.FacilityPrecipitation,
excelList: excelDownList,
isLoading : false,
},
PrecipitationDetail:{
...state.PrecipitationDetail,
gridListPrecipitationDetail: res.detailData,
gridListPrecipitationDetail: res.detailData
}
}))
}
+82 -104
View File
@@ -21,16 +21,12 @@ export interface FacilityWaterQltyProps {
sggNm: string,
addr: string,
fctCpc: number,
inflAssctBfrWqltBod: string | '',
inflAssctAftWqltBod: string | '',
inflAssctBfrWqltToc: string | '',
inflAssctAftWqltToc: string | '',
inflAssctBfrWqltSs: string | '',
inflAssctAftWqltSs: string | '',
inflAssctBfrWqltTn: string | '',
inflAssctAftWqltTn: string | '',
inflAssctBfrWqltTp: string | '',
inflAssctAftWqltTp: string | '',
inflAssctBfrWqltTp: string | '',
efflWqltBod: string | '',
efflWqltToc: string | '',
efflWqltSs: string | '',
@@ -131,11 +127,11 @@ const upHeadList1: TableUpperProps[] = [
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0 },
{ id: "A", title: "유입", colSpan: 5, row: 0 },
{ id: "B", title: "방류", colSpan: 5, row: 0 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 },
{ id: "inflAssctAftWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1 },
{ id: "inflAssctAftWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1 },
{ id: "inflAssctAftWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 },
{ id: "inflAssctAftWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1 },
{ id: "inflAssctAftWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1 },
@@ -155,11 +151,11 @@ const upHeadList2: TableUpperProps[] = [
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2 },
{ id: "A", title: "유입", colSpan: 5, row: 0 },
{ id: "B", title: "방류", colSpan: 5, row: 0 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctAftWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 },
{ id: "inflAssctAftWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctAftWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctAftWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctAftWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 },
@@ -183,11 +179,11 @@ const upHeadList3: TableUpperProps[] = [
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2 },
{ id: "A", title: "유입", colSpan: 5, row: 0 },
{ id: "B", title: "방류", colSpan: 5, row: 0 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctAftWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 },
{ id: "inflAssctAftWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctAftWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "inflAssctAftWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 },
{ id: "inflAssctAftWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 },
@@ -201,10 +197,10 @@ const upHeadList3: TableUpperProps[] = [
// 처리시설 수질현황 헤더(모달-연간)
const upHeadListModalYear: TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe1", upSequnce: 1, align: "right" },
{ id: "inflAssctBfrWqltToc", title: "TOC(COD)\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe1", upSequnce: 3, align: "right" },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" },
{ id: "inflAssctAftWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe1", upSequnce: 1, align: "right" },
{ id: "inflAssctAftWqltToc", title: "TOC(COD)\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" },
{ id: "inflAssctAftWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe1", upSequnce: 3, align: "right" },
{ id: "inflAssctAftWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe1", upSequnce: 3, align: "right" },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe2", upSequnce: 1, align: "right" },
{ id: "efflWqltToc", title: "TOC(COD)\n(mg/L)", upName: "upChangeRe2", upSequnce: 2, align: "right" },
@@ -292,7 +288,6 @@ export type FacilityWaterQltyType = {
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
isLoading: boolean;
},
FacilityWaterQltyModal: {
@@ -316,7 +311,6 @@ export const facilityWaterQltyInitState: FacilityWaterQltyType = {
facilityWaterQltyCount: 0,
facilityWaterQltyList: [],
excelList: [],
isLoading: true,
isInit: false,
mainLabelArray: mainLabelArray,
upHeadList1: upHeadList1,
@@ -367,8 +361,8 @@ export type FacilityWaterQltyActions = {
* @returns : 없음
* @description : 시설수질리스트 타입의 데이터를 표현 방식으로 바꿔주는 함수
* - msrDt : YYYY-MM-DD 형식으로 변환
* - inflAssctBfrWqltBod : 소수점 1자리까지 표현
* - inflAssctBfrWqltTn : 소수점 1자리까지 표현
* - inflAssctAftWqltBod : 소수점 1자리까지 표현
* - inflAssctAftWqltTn : 소수점 1자리까지 표현
* - inflAssctBfrWqltTp : 소수점 1자리까지 표현
* - efflWqltBod : 소수점 2자리까지 표현
* - efflWqltTn : 소수점 2자리까지 표현
@@ -397,48 +391,41 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
* @param fcltyNm : 시설명
*/
searchFacilityWaterQltyList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FacilityWaterQltyType) => ({
...state,
FacilityWaterQltyMain: {
...state.FacilityWaterQltyMain,
isLoading: true,
},
}));
const res = await fetchFacilityWaterQltyList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const rtnData = res.data.map(item => {
dataFormSetting(item)
if(item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3);
if(item.inflAssctAftWqltTn) {
item.inflAssctAftWqltTn = Number(Math.round(Number(item.inflAssctAftWqltTn) * 1000)/1000).toFixed(3);
}
if(item.efflWqltTn){
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3);
}
if(item.inflAssctBfrWqltTp){
item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000)/1000).toFixed(3);
if(item.inflAssctAftWqltTp){
item.inflAssctAftWqltTp = Number(Math.round(Number(item.inflAssctAftWqltTp) * 1000)/1000).toFixed(3);
}
if(item.efflWqltTp){
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltToc){
item.inflAssctAftWqltToc = Number(Math.round(Number(item.inflAssctAftWqltToc) * 10)/10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltBod){
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltBod){
item.inflAssctAftWqltBod = Number(Math.round(Number(item.inflAssctAftWqltBod) * 10)/10).toFixed(1);
}
if(item.efflWqltBod){
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltSs){
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltSs){
item.inflAssctAftWqltSs = Number(Math.round(Number(item.inflAssctAftWqltSs) * 10)/10).toFixed(1);
}
if(item.efflWqltSs){
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltToc){
item.inflAssctAftWqltToc = Number(Math.round(Number(item.inflAssctAftWqltToc) * 10)/10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
@@ -463,11 +450,11 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
시설이름: item.bscFctNm,
주소: item.addr,
용량: item.fctCpc,
유입BOD: item.inflAssctBfrWqltBod,
유입TOC: item.inflAssctBfrWqltToc,
유입SS: item.inflAssctBfrWqltSs,
유입TN: item.inflAssctBfrWqltTn,
유입TP: item.inflAssctBfrWqltTp,
유입BOD: item.inflAssctAftWqltBod,
유입TOC: item.inflAssctAftWqltToc,
유입SS: item.inflAssctAftWqltSs,
유입TN: item.inflAssctAftWqltTn,
유입TP: item.inflAssctAftWqltTp,
유출BOD: item.efflWqltBod,
유출TOC: item.efflWqltToc,
유출SS: item.efflWqltSs,
@@ -489,12 +476,10 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
...state.FacilityWaterQltyMain,
facilityWaterQltyList: rtnData,
facilityWaterQltyCount: res.count,
isLoading : false,
}:{
...state.FacilityWaterQltyMain,
excelList: excelDownList,
isLoading : false,
},
}
}))
},
@@ -571,54 +556,47 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
return;
}
// facilityPrecipitation의 rainEffectDay 계산 로직을 적용
const tmpData:FacilityWaterQltyProps[] = [];
const data = res.data.wqltObjs;
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
for(let idx = 0; idx < data.length; idx++) {
const item = data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay) > 3) {
item.rainEffectDay = 1;
// facilityPrecipitation의 rainEffectDay 계산 로직을 적용
for(let idx = 0; idx < res.data.wqltObjs.length; idx++) {
const item = res.data.wqltObjs[idx];
if (!item) continue;
const rainDay = Number(item.infoRnDay) >= 3 ? 1 : 0;
let rainEffectDay = 0;
if(idx < res.data.wqltObjs.length - 2) {
if(rainDay == 1) {
rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
if(idx >= 2) {
const prevItem1 = res.data.wqltObjs[idx-1];
const prevItem2 = res.data.wqltObjs[idx-2];
if((prevItem1 && Number(prevItem1.infoRnDay) >= 3) || (prevItem2 && Number(prevItem2.infoRnDay) >= 3)) {
rainEffectDay = 1;
}
}
}
} else if(idx < res.data.wqltObjs.length - 1) {
const nextItem = res.data.wqltObjs[idx+1];
if(rainDay == 1 || (nextItem && Number(nextItem.infoRnDay) >= 3)) {
rainEffectDay = 1;
}
} else {
rainEffectDay = rainDay;
}
tmpData.push({
...item,
rainEffectDay: rainEffectDay,
} as FacilityWaterQltyProps);
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < data.length; idx++) {
if(data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < data.length; idx++) {
if(data[idx] && data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if(data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) > 3) {
data[idx]!.infoRnDay = data[idx-1]!.infoRnDay;
}
}
if(idx > 2){
if(data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) > 3) {
data[idx]!.infoRnDay = data[idx-2]!.infoRnDay;
}
}
}
}
const rtnData = data.map((item: FacilityWaterQltyProps) => {
const rtnData = tmpData.map((item: FacilityWaterQltyProps) => {
dataFormSetting(item)
if(item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3);
if(item.inflAssctAftWqltTn) {
item.inflAssctAftWqltTn = Number(Math.round(Number(item.inflAssctAftWqltTn) * 1000)/1000).toFixed(3);
}
if(item.efflWqltTn){
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3);
@@ -629,26 +607,26 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
if(item.efflWqltTp){
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltToc){
item.inflAssctAftWqltToc = Number(Math.round(Number(item.inflAssctAftWqltToc) * 10)/10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltBod){
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltBod){
item.inflAssctAftWqltBod = Number(Math.round(Number(item.inflAssctAftWqltBod) * 10)/10).toFixed(1);
}
if(item.efflWqltBod){
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltSs){
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltSs){
item.inflAssctAftWqltSs = Number(Math.round(Number(item.inflAssctAftWqltSs) * 10)/10).toFixed(1);
}
if(item.efflWqltSs){
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if(item.inflAssctAftWqltToc){
item.inflAssctAftWqltToc = Number(Math.round(Number(item.inflAssctAftWqltToc) * 10)/10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
+33 -46
View File
@@ -170,6 +170,7 @@ const fetchFlowRateList = async (pageNo: number, pageSize: number, searchYear: s
try {
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
console.log(url);
return { data: res.data, count: res.count }
} catch (error) {
console.error('시설정보 유량현황 데이터를 가져오는데 실패했습니다:', error);
@@ -219,7 +220,6 @@ export type FlowRateSearchType = {
flowRateList:flowRateListProps[];
flowRateCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
FlowRateModal : {
@@ -253,8 +253,7 @@ export const flowRateSearchInitState:FlowRateSearchType = {
upHeadList3 : upHeadList3,
flowRateList : flowRateList,
flowRateCount : 0,
excelList: [],
isLoading: true,
excelList: []
},
FlowRateModal : {
isInit : false,
@@ -266,13 +265,6 @@ export const flowRateSearchInitState:FlowRateSearchType = {
export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => FlowRateSearchType) => void)=>FlowRateSearchActions=(set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => {
return {
searchFlowRateList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FlowRateSearchType) => ({
...state,
FlowRateList: {
...state.FlowRateList,
isLoading: true,
},
}));
const res = await fetchFlowRateList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
const excelDownList: ExcelType[] = [];
@@ -311,59 +303,54 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow
...state.FlowRateList,
flowRateList: rtnData,
flowRateCount: res.count,
isLoading : false,
}:{
...state.FlowRateList,
excelList: excelDownList,
isLoading : false,
},
}
}))
},
searchFlowRateModalList: async (bscFctCd: string, searchYear: string) => {
const res = await fetchFlowRateModalList(bscFctCd, searchYear);
const data = res.data;
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
const tmpData:FlowRateModalProps[] = [];
data.forEach((item: FlowRateModalProps) => {
if(item.infoRnDay && item.infoRnDay.toString().trim() === 'x') {
item.infoRnDay = '';
}
});
// facilityPrecipitation의 rainEffectDay 계산 로직을 적용
for(let idx = 0; idx < data.length; idx++) {
const item = data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay.toString().trim()) >= 3) {
item.rainEffectDay = 1;
const rainDay = Number(item.infoRnDay) >= 3 ? 1 : 0;
let rainEffectDay = 0;
if(idx < data.length - 2) {
if(rainDay == 1) {
rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
}
}
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < data.length; idx++) {
if(data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < data.length; idx++) {
if(data[idx] && data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if(data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.infoRnDay = data[idx-1]!.infoRnDay;
if(idx >= 2) {
if(Number(data[idx-1].infoRnDay) >= 3 || Number(data[idx-2].infoRnDay) >= 3) {
rainEffectDay = 1;
}
}
}
if(idx > 2){
if(data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.infoRnDay = data[idx-2]!.infoRnDay;
}
} else if(idx < data.length - 1) {
if(rainDay == 1 || Number(data[idx+1].infoRnDay) >= 3) {
rainEffectDay = 1;
}
} else {
rainEffectDay = rainDay;
}
tmpData.push({
...item,
rainEffectDay: rainEffectDay,
});
}
const rtnData = data.map((item: FlowRateModalProps) => {
const rtnData = tmpData.map((item: FlowRateModalProps) => {
item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0)
dataFormSetting(item);
return item;
+4 -36
View File
@@ -1,7 +1,6 @@
import DataForm from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
import { getFetch } from "@/app/components/api";
import { calRainEffectDay, type ApiResponse, type FlowDataItem } from "../underWaterInput";
export type { TableUpperProps };
/**====================================
* Store - 타입
@@ -146,7 +145,6 @@ export type PlanSewageType = {
planSewageList: PlanSewageProps[];
planSewageCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
}
@@ -163,8 +161,7 @@ export const planSewageInitState: PlanSewageType = {
upHeadList3 : upHeadList3,
planSewageList : planSewageList,
planSewageCount : 0,
excelList : [],
isLoading : true,
excelList : []
},
}
@@ -173,43 +170,16 @@ export type PlanSewageStore = PlanSewageType & PlanSewageActions;
export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageType) => void)=>PlanSewageActions=(set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => {
return {
searchPlanSewageList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: PlanSewageType) => ({
...state,
PlanSewage: {
...state.PlanSewage,
isLoading: true,
},
}));
const res = await fetchPlanSewageList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
const excelDownList: ExcelType[] = [];
const data = res.data
const processedData = await Promise.all(data.map(async (item:PlanSewageProps) => {
const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse;
const calData = calRainEffectDay(res2.data, 'SUNNY');
let sumInflAmntSunny = 0;
let avgInflAmntSunny = 0;
calData.forEach((flowItem:FlowDataItem) => {
sumInflAmntSunny += Number(flowItem.inflAmnt);
})
avgInflAmntSunny = sumInflAmntSunny / calData.length;
item.avgInflAmntSunny = avgInflAmntSunny;
if(item.bscFctCd === '11200PB001R'){
console.log('avgInflAmntSunny : ',item.avgInflAmntSunny);
console.log('calData : ',calData);
}
return item;
}));
console.log('res' , res.data);
/**
* 결과데이터 계산
* (1) 여유용량 = 시설용량 - 건기시 평균유량
* (2) 변동부하율 = 건기시 일최대 유량/일평균유량(기준 최근 3개년)
* (3) 분류식화율 = 분류식지역 면적(㎢)/처리구역 면적합계(㎢) ×100
*/
const resultData = processedData.map((item:PlanSewageProps) => {
console.log('item.fctCpc : ',item.fctCpc);
console.log('item.avgInflAmntSunny : ',item.avgInflAmntSunny);
const resultData = res.data.map((item:PlanSewageProps) => {
item.spareCapacity = Number(item.fctCpc) - Number(item.avgInflAmntSunny);
item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny!==0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0;
item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr!==0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0;
@@ -246,12 +216,10 @@ export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageTy
...state.PlanSewage,
planSewageList: resultData,
planSewageCount: res.count,
isLoading : false,
}:{
...state.PlanSewage,
excelList: excelDownList,
isLoading : false,
},
}
}))
}
}
+45 -66
View File
@@ -1,7 +1,6 @@
import { postFetch } from "@/app/components/api";
import DataForm from "@/app/components/common/DataForm";
import { fetchPlanInfo } from "../common";
import { getFetchAreaList, postFetch } from "@/app/components/api";
import type { TableUpperProps } from "../dashboard";
import DataForm from "@/app/components/common/DataForm";
export type { TableUpperProps };
/**====================================
* Store - 타입
@@ -228,14 +227,25 @@ const fetchFacilityDetailInfo = async (swtrmtFcltCd: string) => {
};
// 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우)
const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm : string | undefined, sggNm : string | undefined, targetYear : string | undefined, set : (fn: (state: ProcessAreaType) => ProcessAreaType) => void): Promise<{data:ProcessAreaProps[], count:number}> => {
const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm : string | undefined, sggNm : string | undefined, targetYear : string | undefined ): Promise<{data:ProcessAreaProps[], count:number}> => {
try {
const res = await fetchPlanInfo(targetYear, ctpvNm, sggNm, undefined);
targetYear = targetYear ? targetYear : "2024";
const baseUrl = 'https://apigateway.rsonesoft.com/dc-service/api/v1/nowDmgMtncGnsvy';
const queryParams = new URLSearchParams();
if (ctpvNm && ctpvNm !== '전체') queryParams.append('ctpvNm', ctpvNm);
if (sggNm && sggNm !== '전체') queryParams.append('sggNm', sggNm);
if (targetYear) queryParams.append('targetYear',targetYear);
const queryString = queryParams.toString();
const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
const res = await getFetchAreaList(url);
if(res && res.length > 0){
const enrichedData = await Promise.all(
res.map(async (item: ProcessAreaProps) => {
upHeadList1.forEach((head:TableUpperProps) => {
/* if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재\n(' + item.yr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계\n(' + item.yrDc1 + '년)';
@@ -247,19 +257,6 @@ const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm :
head.title = '4단계\n(' + item.yrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계(' + item.yrDt4 + '년)';
} */
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계';
}
});
const res = await fetchFacilityDetailInfo(item.swtrmtFcltCd);
@@ -283,13 +280,6 @@ const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm :
}
} catch (error) {
console.error('시설계획정보를 가져오는데 실패했습니다:', error);
set((state) => ({
...state,
ProcessArea : {
...state.ProcessArea,
isLoading : false
}
}));
return {data: [], count: 0};
}
};
@@ -314,7 +304,6 @@ export type ProcessAreaType = {
processAreaList: ProcessAreaProps[];
processAreaCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
ProcessAreaDetail : {
@@ -339,8 +328,7 @@ export const processAreaInitState: ProcessAreaType = {
upHeadList1 : upHeadList1,
processAreaList : processAreaList,
processAreaCount : 0,
excelList : [],
isLoading : true,
excelList : []
},
ProcessAreaDetail : {
@@ -367,14 +355,7 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set:
* @param pageSize : 페이지 크기
*/
searchProcessAreaList: async ( pageNo:number, pageSize:number, ctpvNm?:string, sggNm?:string, targetYear?:string) => {
set((state: ProcessAreaType) => ({
...state,
ProcessArea: {
...state.ProcessArea,
isLoading: true,
},
}));
const res = await fetchProcessAreaList(pageNo, pageSize, ctpvNm, sggNm, targetYear, set);
const res = await fetchProcessAreaList(pageNo, pageSize, ctpvNm, sggNm, targetYear);
res.data.forEach((item:ProcessAreaProps) => {
DataForm({ type: 'float1', column: 'fctCpc', item:item as unknown as Record<string, unknown>});
})
@@ -419,11 +400,9 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set:
...state.ProcessArea,
processAreaList: res.data,
processAreaCount: res.count,
isLoading : false,
}:{
...state.ProcessArea,
excelList: excelDownList,
isLoading : false,
},
}))
},
@@ -432,51 +411,51 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set:
set((state: ProcessAreaType) => {
const rtnData = state.ProcessArea.processAreaList.find((item: ProcessAreaProps) => item.swtrmtFcltCd === swtrmtFcltCd);
if (rtnData) {
upHeadListFcltyImproveInfo.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.yr? '현재\n(' + rtnData.yr + '년)':head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.yrDc1? '1단계\n(' + rtnData.yrDc1 + '년)':head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.yrDc2? '2단계\n(' + rtnData.yrDc2 + '년)':head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.yrDc3? '3단계\n(' + rtnData.yrDc3 + '년)':head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.yrDc4? '4단계\n(' + rtnData.yrDc4 + '년)':head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.yrDt4? '기승인\n4단계(' + rtnData.yrDt4 + '년)':head.title = '기승인\n4단계';
}
});
upHeadListFcltyImproveInfo.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재\n(' + rtnData.yr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계\n(' + rtnData.yrDc1 + '년)';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계\n(' + rtnData.yrDc2 + '년)';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계\n(' + rtnData.yrDc3 + '년)';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계\n(' + rtnData.yrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계(' + rtnData.yrDt4 + '년)';
}
});
upHeadListProcessAreaPlan.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.yr? '현재\n(' + rtnData.yr + '년)':head.title = '현재';
head.title = '현재\n(' + rtnData.yr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.yrDc1?'1단계\n(' + rtnData.yrDc1 + '년)':head.title = '1단계';
head.title = '1단계\n(' + rtnData.yrDc1 + '년)';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.yrDc2?'2단계\n(' + rtnData.yrDc2 + '년)':head.title = '2단계';
head.title = '2단계\n(' + rtnData.yrDc2 + '년)';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.yrDc3? '3단계\n(' + rtnData.yrDc3 + '년)':head.title = '3단계';
head.title = '3단계\n(' + rtnData.yrDc3 + '년)';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.yrDc4?'4단계\n(' + rtnData.yrDc4 + '년)':head.title = '4단계';
head.title = '4단계\n(' + rtnData.yrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.yrDt4?'기승인\n4단계(' + rtnData.yrDt4 + '년)':head.title = '기승인\n4단계';
head.title = '기승인\n4단계(' + rtnData.yrDt4 + '년)';
}
});
upHeadListProcessPopulation.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.yr?'현재\n(' + rtnData.yr + '년)':head.title = '현재';
head.title = '현재\n(' + rtnData.yr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.yrDc1?'1단계\n(' + rtnData.yrDc1 + '년)':head.title = '1단계';
head.title = '1단계\n(' + rtnData.yrDc1 + '년)';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.yrDc2?'2단계\n(' + rtnData.yrDc2 + '년)':head.title = '2단계';
head.title = '2단계\n(' + rtnData.yrDc2 + '년)';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.yrDc3?'3단계\n(' + rtnData.yrDc3 + '년)':head.title = '3단계';
head.title = '3단계\n(' + rtnData.yrDc3 + '년)';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.yrDc4?'4단계\n(' + rtnData.yrDc4 + '년)':head.title = '4단계';
head.title = '4단계\n(' + rtnData.yrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.yrDt4?'기승인\n4단계(' + rtnData.yrDt4 + '년)':head.title = '기승인\n4단계';
head.title = '기승인\n4단계(' + rtnData.yrDt4 + '년)';
}
});
+1 -20
View File
@@ -517,7 +517,6 @@ export type ProcessFacilityType = {
processFacilityList:facilityListProps[];
processFacilityCount:number;
excelList : ExcelType[];
isLoading: boolean;
},
ProcessFacilityDetail : {
@@ -552,8 +551,7 @@ export const processFacilityInitState:ProcessFacilityType = {
upHeadList3 : upHeadList3,
processFacilityList : processFacilityList,
processFacilityCount:1,
excelList : [],
isLoading : true,
excelList : []
},
ProcessFacilityDetail : {
@@ -590,13 +588,6 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio
* @param pageSize : 페이지 크기
*/
searchProcessFacility: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => {
set((state: ProcessFacilityType) => ({
...state,
ProcessFacilityList: {
...state.ProcessFacilityList,
isLoading: true,
},
}));
const res = await fetchFacilityList(pageNo, pageSize, partValue, nameCd, fcltCpct, oprtngSttsCd, facilityPartValue, facilityName);
res.data.forEach((item:facilityListProps) => {
DataForm({ type: 'date', column: 'cmplDt', item:item as unknown as Record<string, unknown>});
@@ -644,11 +635,9 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio
...state.ProcessFacilityList,
processFacilityList: res.data,
processFacilityCount: res.count,
isLoading: false,
}:{
...state.ProcessFacilityList,
excelList: excelDownList,
isLoading: false,
},
}))
},
@@ -659,13 +648,6 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio
* @param pageSize : 페이지 크기
*/
searchProcessFacilitySearching: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => {
set((state: ProcessFacilityType) => ({
...state,
ProcessFacilityList: {
...state.ProcessFacilityList,
isLoading: true,
},
}));
const res = await fetchFacilityListSearching(pageNo, pageSize, partValue, nameCd, fcltCpct, oprtngSttsCd, facilityPartValue, facilityName);
/* res.data.forEach((item:facilityListProps) => {
DataForm({ type: 'date', column: 'cmplDt', item:item as unknown as Record<string, unknown>});
@@ -683,7 +665,6 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio
...state.ProcessFacilityList,
processFacilityList: res.data,
processFacilityCount: res.count,
isLoading: false,
},
}))
},
+2 -14
View File
@@ -183,7 +183,6 @@ export type RdiType = {
rdiList: RdiProps[]; // Changed from facilityAreaProps to ProcessAreaProps
rdiCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
}
@@ -200,8 +199,7 @@ export const rdiInitState: RdiType = {
upHeadList3 : upHeadList3,
rdiList : rdiList,
rdiCount : 2,
excelList : [],
isLoading : true,
excelList : []
}
}
@@ -222,14 +220,6 @@ export const rdiReducer:(set:SetStateFunction)=>RdiActions=(set: SetStateFunctio
console.log("tableActionsExport");
return {
searchRdiList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: RdiType) => ({
...state,
Rdi: {
...state.Rdi,
isLoading: true,
},
}));
const res = await fetchRdiList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
const excelDownList: ExcelType[] = [];
@@ -274,12 +264,10 @@ export const rdiReducer:(set:SetStateFunction)=>RdiActions=(set: SetStateFunctio
...state.Rdi,
rdiList: rtnData,
rdiCount: res.count,
isLoading : false,
}:{
...state.Rdi,
excelList: excelDownList,
isLoading : false,
},
}
}))
},
}
+13 -88
View File
@@ -126,6 +126,7 @@ const tempSewageOccurList:modalTableType[] = []
const fetchSewageOccurList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
// 20250701임시시
console.log("searchYear", searchYear);
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
@@ -144,7 +145,7 @@ const fetchSewageOccurList = async (pageNo: number, pageSize: number, searchYear
====================================*/
export type SewageOccurActions = {
searchSewageOccurList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
searchSewageOccurDetailList: (bscFctCd: string, searchYear: string, startYearMonth?: string, endYearMonth?: string) => void;
searchSewageOccurDetailList: (bscFctCd: string, searchYear: string) => void;
}
export type SewageOccurType = {
@@ -161,7 +162,6 @@ export type SewageOccurType = {
sewageOccurList: SewageOccurProps[]; // Changed from facilityAreaProps to ProcessAreaProps
sewageOccurCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
SewageOccurDetail : {
@@ -184,8 +184,7 @@ export const sewageOccurInitState: SewageOccurType = {
upHeadList3 : upHeadList3,
sewageOccurList : sewageOccurList,
sewageOccurCount : 2,
excelList : [],
isLoading : true,
excelList : []
},
SewageOccurDetail : {
@@ -198,15 +197,14 @@ export const sewageOccurInitState: SewageOccurType = {
export type SewageOccurStore = SewageOccurType & SewageOccurActions;
// Add type definitions for API responses
export type FlowDataItem = {
type FlowDataItem = {
inflAmnt: string | number;
infoRnDay: string | number;
bscFctCd: string;
msrDt: string;
rainEffectDay?: number;
}
export type FlowResponse = {
type FlowResponse = {
data: FlowDataItem[];
count: number;
}
@@ -214,84 +212,28 @@ export type FlowResponse = {
export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
return {
searchSewageOccurList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: SewageOccurType) => ({
...state,
SewageOccur: {
...state.SewageOccur,
isLoading: true,
},
}));
const res = await fetchSewageOccurList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
// Promise.all을 사용하여 모든 비동기 작업이 완료될 때까지 기다림
const calData = await Promise.all(data.map(async (item: SewageOccurProps) => {
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.swageChangePercent = 80;
const bscFctCd = item.bscFctCd;
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as FlowResponse;
let sumChungcunDay = 0;
let chungcunSumFlow = 0;
let totWaterUsage = 0;
if(bscFctCd === '11200PB001R'){
console.log('res2.data : ',res2.data);
}
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
for(let idx = 0; idx < res2.data.length; idx++) {
const item = res2.data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay.toString().trim()) >= 3) {
item.rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
}
}
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < res2.data.length; idx++) {
if(res2.data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && res2.data[idx-1]?.infoRnDay && Number(res2.data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
res2.data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && res2.data[idx-2]?.infoRnDay && Number(res2.data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
res2.data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < res2.data.length; idx++) {
if(res2.data[idx] && res2.data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if(res2.data[idx-1]?.infoRnDay && Number(res2.data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
res2.data[idx]!.infoRnDay = res2.data[idx-1]!.infoRnDay;
}
}
if(idx > 2){
if(res2.data[idx-2]?.infoRnDay && Number(res2.data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
res2.data[idx]!.infoRnDay = res2.data[idx-2]!.infoRnDay;
}
}
}
}
if(bscFctCd === '11200PB001R'){
console.log('calData : ',res2.data);
}
res2.data.forEach((item: FlowDataItem) => {
if(Number(item.rainEffectDay) === 0){
if(Number(item.infoRnDay) ===0){
chungcunSumFlow += Number(item.inflAmnt);
sumChungcunDay += 1;
}
totWaterUsage += Number(item.inflAmnt);
});
const avg = totWaterUsage /res2.count;
@@ -308,34 +250,17 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
...state.SewageOccur,
sewageOccurList: calData,
sewageOccurCount: res.count,
isLoading : false,
}:{
...state.SewageOccur,
excelList: [],
isLoading : false,
},
}
}))
},
searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYearMonth?: string, endYearMonth?: string) => {
searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string) => {
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
const monthData: SewageOccurDetailProps[] = [];
let tot = 0, cnt= 0;
console.log('startYearMonth : ', startYearMonth, 'endYearMonth : ', endYearMonth);
if(startYearMonth) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month >= startYearMonth;
});
}
if(endYearMonth) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month <= endYearMonth;
});
}
let tot = 0, cnt= 0
res.data.forEach((item: FlowDataItem) => {
const month = item.msrDt?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
@@ -359,7 +284,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
monthData.forEach((item, index) => {
item.usege = item.sum/item.cnt *0.65
tableData.push({
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
msrDt: item.yr+'-'+(index+1>10?String(index+1):'0'+(index+1)),
waterUsage: Math.round(item.usege*100) /100,
swageChangePercent: (Math.round((item.usege/item.usege*0.8) * 100) / 100) * 100,
estimationSewage: Math.round(item.usege*0.8 * 100) / 100
+1 -1
View File
@@ -59,7 +59,7 @@ export const StoreZus =
}
) => {
return createStore<FoStore>()((set) => {
LoginApi.login({userId: "CLEANWATER", password: "gktneh12!@"})
LoginApi.login({userId: "admin1gmail", password: "test1234!"})
return {
...initState,
...CommonReducer(set),
+30 -114
View File
@@ -2,15 +2,8 @@ import DataForm from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
import { getFetch } from "@/app/components/api";
import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps } from "./types";
import type { SewageOccurDetailProps } from "../sewageOccur";
export type { TableUpperProps };
// SewageOccurDetailProps 타입을 여기에 정의
export type SewageOccurDetailProps = {
cnt : number,
sum : number,
yr:string,
usege:number
}
/**====================================
* Store - 타입
====================================*/
@@ -82,7 +75,7 @@ const upHeadList3:TableUpperProps[] = [
// 모달
const upHeadListUnderWaterDetail:TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)" },
{ id: "realSewageInput", title: "실제 하수유입량\n(m³/일)" },
{ id: "sewageOccur", title: "오수발생량\n(m³/일)" },
{ id: "underWaterInput", title: "지하수 유입량\n(m³/일)" },
];
@@ -169,15 +162,13 @@ const underWaterDetailList:UnderWaterInputModalProps[] = [
====================================*/
// API response types
export interface FlowDataItem {
inflAmnt: number | string;
interface FlowDataItem {
inflAmnt: number;
infoRnDay: number;
msrDt: string;
rainEffectDay? : number;
sumFlow? : number | string | '';
}
export interface ApiResponse {
interface ApiResponse {
data: FlowDataItem[];
count: number;
}
@@ -218,7 +209,6 @@ export type UnderWaterType = {
underWaterList: UnderWaterProps[]; // Changed from facilityAreaProps to ProcessAreaProps
underWaterCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
UnderWaterDetail : {
@@ -241,8 +231,7 @@ export const underWaterInitState: UnderWaterType = {
upHeadList3 : upHeadList3,
underWaterList : underWaterList,
underWaterCount : 4,
excelList : [],
isLoading : true,
excelList : []
},
UnderWaterDetail : {
@@ -261,70 +250,9 @@ const dataFormSetting=(item : UnderWaterProps)=> {
export type UnderWaterStore = UnderWaterType & UnderWaterActions;
export const calRainEffectDay = (data: FlowDataItem[], weather: string) => {
// 강우영향일 계산 (강우량이 3 이상이면 무조건 강우영향일)
for(let idx = 0; idx < data.length; idx++) {
const item = data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay.toString().trim()) >= 3) {
item.rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
}
}
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < data.length; idx++) {
if(data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < data.length; idx++) {
if(data[idx] && data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if(data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.infoRnDay = data[idx-1]!.infoRnDay;
}
}
if(idx > 2){
if(data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.infoRnDay = data[idx-2]!.infoRnDay;
}
}
}
}
let rtnData : FlowDataItem[] = [];
if (weather === 'ALL') {
rtnData = data;
} else if (weather === 'SUNNY') {
rtnData = data.filter((item: FlowDataItem) => item.rainEffectDay === 0);
} else {
rtnData = data.filter((item: FlowDataItem) => item.rainEffectDay === 1);
}
return rtnData;
}
export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterType) => void)=>UnderWaterActions=(set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => {
return {
searchUnderWaterList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
isLoading: true,
},
}));
const res = await fetchUnderWaterList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
const calData = await Promise.all(data.map(async (item: UnderWaterProps) => {
@@ -334,7 +262,8 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
const bscFctCd = item.bscFctCd;
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as ApiResponse;
const calData = calRainEffectDay(res2.data, 'SUNNY');
let sumChungcunDay = 0;
let chungcunSumFlow = 0;
let sumSummerChungcunDay = 0;
@@ -343,25 +272,24 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
let sumWinterChungcunDay = 0;
let sumWinterChungcunFlow = 0;
calData.forEach((flowItem: FlowDataItem) => {
chungcunSumFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
if(flowItem.msrDt.substring(4,6) ==='06' || flowItem.msrDt.substring(4,6) ==='07' || flowItem.msrDt.substring(4,6) ==='08'){
sumSummerChungcunDay += 1;
sumSummerChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
}else if(flowItem.msrDt.substring(4,6) ==='01' || flowItem.msrDt.substring(4,6) ==='02'){
sumWinterChungcunDay += 1;
sumWinterChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
res2.data.forEach((flowItem: FlowDataItem) => {
// 청천시
if(Number(flowItem.infoRnDay) ===0){
sumChungcunDay += 1;
chungcunSumFlow += Number(flowItem.inflAmnt);
if(flowItem.msrDt.substring(4,6) ==='06' || flowItem.msrDt.substring(4,6) ==='07' || flowItem.msrDt.substring(4,6) ==='08'){
sumSummerChungcunDay += 1;
sumSummerChungcunFlow += Number(flowItem.inflAmnt);
}else if(flowItem.msrDt.includes('01') || flowItem.msrDt.includes('02')){
sumWinterChungcunDay += 1;
sumWinterChungcunFlow += Number(flowItem.inflAmnt);
}
}
});
const usage = chungcunSumFlow / calData.length;
const summerUsage = sumSummerChungcunFlow / sumSummerChungcunDay;
const winterUsage = sumWinterChungcunFlow / sumWinterChungcunDay;
item.underWaterInputYear = Math.round((usage-(usage*0.65*0.8)) * 100) / 100;
item.underWaterInputSummer = Math.round((summerUsage-(summerUsage*0.65*0.8)) * 100) / 100;
item.underWaterInputWinter = Math.round((winterUsage-(winterUsage*0.65*0.8)) * 100) / 100;
item.underWaterInputYear = Number(chungcunSumFlow==0?0:Math.round((chungcunSumFlow / sumChungcunDay) * 10) / 10) - Number(item.fctCpc * 0.6 * 0.8);
item.underWaterInputSummer = Number(sumSummerChungcunFlow==0?0:Math.round((sumSummerChungcunFlow / sumSummerChungcunDay) * 10) / 10) - Number(item.fctCpc * 0.6 * 0.8);
item.underWaterInputWinter = Number(sumWinterChungcunFlow==0?0:Math.round((sumWinterChungcunFlow / sumWinterChungcunDay) * 10) / 10) - Number(item.fctCpc * 0.6 * 0.8);
return item;
}));
@@ -404,30 +332,17 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
...state.UnderWater,
underWaterList: calData,
underWaterCount: res.count,
isLoading : false,
}:{
...state.UnderWater,
isLoading : false,
excelList: excelDownList
},
excelList: excelDownList,
}
}))
},
unserWaterModal:async (bscFctCd, searchYear)=>{
console.log('searchYear : ', searchYear);
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
const monthData: SewageOccurDetailProps[] = [];
const calData = calRainEffectDay(res.data, 'SUNNY');
let tot = 0, cnt= 0;
let tmpTot = 0;
calData.forEach((item: FlowDataItem) => {
tmpTot += Number(item.inflAmnt);
})
console.log('tmpTot : ', tmpTot/calData.length);
calData.forEach((item: FlowDataItem) => {
let tot = 0, cnt= 0
res.data.forEach((item: FlowDataItem) => {
const month = item.msrDt?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
if (monthIdx >= 0) {
@@ -449,7 +364,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
monthData.forEach((item, index) => {
item.usege = item.sum/item.cnt
tableData.push({
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
msrDt: item.yr+'-'+(index+1>10?String(index+1):'0'+(index+1)),
realSewageInput:Math.round(item.usege*100) /100,
sewageOccur:Math.round(item.usege*0.65*0.8 * 100) / 100,
underWaterInput:Math.round((item.usege-(item.usege*0.65*0.8)) * 100) / 100,
@@ -464,6 +379,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
});
avgWaterUsage = tot/cnt
const newData= [
{
msrDt: '평균',
@@ -17,6 +17,8 @@ export class LoginApiService implements LoginService {
public async login(payload: ILogin): Promise<void> {
try {
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
console.log(payload.userId+' '+payload.password)
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
method: "POST",
body: JSON.stringify({
@@ -28,20 +28,20 @@ export const MsSwagePplCol = [
// { id: 'lyrTypeNm', title: '레이어타입명' },
]
export const MsSwagePplCol2 = [
{ id: 'rowNumber', title: '일련\n번호' },
{ id: 'fcltMngNo', title: '시설\n관리번호' },
{ id: 'instMngNo', title: '기관\n관리번호' },
{ id: 'rowNumber', title: '일련번호' },
{ id: 'fcltMngNo', title: '시설 관리번호' },
{ id: 'instMngNo', title: '기관 관리번호' },
{ id: 'instlYmd', title: '설치일자' },
// { id: 'mapshtNo', title: '도엽번호' },
{ id: 'pdmt', title: '관경\n(mm)' },
{ id: 'prlg', title: '연장\n(m)' },
{ id: 'avgGrdn', title: '평균구배\n(m/m)' },
{ id: 'tmptDpth', title: '시점깊이\n(m)' },
{ id: 'tmptMhlMngNo', title: '시점맨홀\n관리번호' },
{ id: 'scendDpth', title: '종점깊이\n(m)' },
{ id: 'scendMhlMngNo', title: '종점맨홀\n관리번호' },
{ id: 'vrtcLen', title: '세로길이\n(m)' },
{ id: 'wdthLen', title: '가로길이\n(m)' },
{ id: 'pdmt', title: '관경(mm)' },
{ id: 'prlg', title: '연장(m)' },
{ id: 'avgGrdn', title: '평균구배(m/m)' },
{ id: 'tmptDpth', title: '시점깊이(m)' },
{ id: 'tmptMhlMngNo', title: '시점맨홀 관리번호' },
{ id: 'scendDpth', title: '종점깊이(m)' },
{ id: 'scendMhlMngNo', title: '종점맨홀 관리번호' },
{ id: 'vrtcLen', title: '세로길이(m)' },
{ id: 'wdthLen', title: '가로길이(m)' },
// { id: 'fcltyShpCd', title: '시설물형태코드' },
// { id: 'fid', title: 'FID' },
// { id: 'ftreSmbolCd', title: '지형지물부호코드' },
@@ -287,19 +287,19 @@ export const SwtrmtFcltCol = [
{ id: 'ycrd', title: 'Y좌표' },
// { id: 'oprtngSttsCd', title: '가동상태코드' },
{ id: 'rprs_msrc_cn', title: '대표공법내용' },
// { id: 'stty_crtr_bod', title: '법정기준생물화학적산소요구량(mg/L)' },
// { id: 'stty_crtr_toc', title: '법정기준TOC((mg/L))' },
// { id: 'stty_crtr_ss', title: '법정기준SS(mg/L)' },
// { id: 'stty_crtr_tn', title: '법정기준총질소(mg/L)' },
// { id: 'stty_crtr_tph', title: '법정기준총인(mg/L)' },
// { id: 'stty_crtr_clbcl_cnt', title: '법정기준대장균수(군수/100mL)' },
{ id: 'stty_crtr_bod', title: '법정기준생물화학적산소요구량(mg/L)' },
{ id: 'stty_crtr_toc', title: '법정기준TOC((mg/L))' },
{ id: 'stty_crtr_ss', title: '법정기준SS(mg/L)' },
{ id: 'stty_crtr_tn', title: '법정기준총질소(mg/L)' },
{ id: 'stty_crtr_tph', title: '법정기준총인(mg/L)' },
{ id: 'stty_crtr_clbcl_cnt', title: '법정기준대장균수(군수/100mL)' },
{ id: 'bsn_nm', title: '유역명' },
// { id: 'obsrvnSptCd', title: '관측지점코드' },
];
export const SwtrmtFcltCol2 = [
{ id: 'rowNumber', title: '일련\n번호' },
{ id: 'swtrmtFcltNm', title: '하수처리\n시설명' },
{ id: 'fcltCpct', title: '시설\n용량\n(㎥/d)' },
{ id: 'rowNumber', title: '일련번호' },
{ id: 'swtrmtFcltNm', title: '하수처리시설명' },
{ id: 'fcltCpct', title: '시설용량(㎥/d)' },
{ id: 'rgnExpln', title: '지역설명' },
// { id: 'cmcnYmd', title: '준공일자' },
{ id: 'oprtngStrtYmd', title: '가동개시일자' },
@@ -311,7 +311,7 @@ export const SwtrmtFcltCol2 = [
// { id: 'sggNm', title: '시군구명' },
// { id: 'sareaCd', title: '권역코드' },
{ id: 'sareaNm', title: '권역명' },
// { id: 'lrgeSareaNm', title: '대권역명' },
{ id: 'lrgeSareaNm', title: '대권역명' },
{ id: 'rvrNm', title: '하천명' },
// { id: 'addr', title: '주소' },
// { id: 'dtlAddr', title: '상세주소' },
@@ -320,19 +320,19 @@ export const SwtrmtFcltCol2 = [
{ id: 'dschgWtstNm', title: '방류수계명' },
// { id: 'pllnArea', title: '부지면적(m²)' },
// { id: 'mngRprtvBzentyNm', title: '관리대행업체명' },
{ id: 'swtrmtPpltnCnt', title: '하수\n처리\n인구수\n(인)' },
{ id: 'swtrmtPpltnCnt', title: '하수처리인구수(인)' },
// { id: 'prcsZoneAreaSum', title: '처리구역면적합계(m²)' },
// { id: 'xcrd', title: 'X좌표' },
// { id: 'ycrd', title: 'Y좌표' },
// { id: 'oprtngSttsCd', title: '가동상태코드' },
{ id: 'rprsMsrcCn', title: '대표\n공법\n내용' },
{ id: 'rprsMsrcCn', title: '대표공법내용' },
// { id: 'sttyCrtrBod', title: '법정기준생물화학적산소요구량(mg/L)' },
// { id: 'sttyCrtrToc', title: '법정기준TOC(mg/L)' },
// { id: 'sttyCrtrSs', title: '법정기준SS(mg/L)' },
// { id: 'sttyCrtrTn', title: '법정기준총질소(mg/L)' },
// { id: 'sttyCrtrTph', title: '법정기준총인(mg/L)' },
// { id: 'sttyCrtrClbclCnt', title: '법정기준대장균수(군수/100mL)' },
// { id: 'bsnNm', title: '유역명' },
{ id: 'bsnNm', title: '유역명' },
// { id: 'obsrvnSptCd', title: '관측지점코드' },
];
@@ -353,9 +353,9 @@ export const SwtrmtPrcsZoneCol2 = [
{ id: 'swtrmtZoneNm', title: '하수처리구역명' },
// { id: 'swtrmt_fclt_cd', title: '하수처리시설코드' },
// { id: 'ctpv_cd', title: '시도코드' },
{ id: 'ctpvNm', title: '시도' },
{ id: 'ctpvNm', title: '시도명' },
// { id: 'sgg_cd', title: '시군구코드' },
{ id: 'sggNm', title: '시군구' },
{ id: 'sggNm', title: '시군구명' },
{ id: 'swtrmtFcltNm', title: '하수처리시설명' },
];
@@ -12,114 +12,20 @@ const inputColumn = [
{ id: "swtrmtZoneCd", title: "처리구역", type: "input" },
];
const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
const Ssc = ({ featureData, isMainSsc, rainMeasureData, onSaveClick }: {
featureData: any,
isMainSsc?: boolean,
chmbrXcnts?: string,
chmbrYdnts?: string,
rainMeasureData?: any,
onSaveClick?: () => void
}) => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isDataLoaded, setIsDataLoaded] = useState(false);
const [formData, setFormData] = useState<any>({});
const [rainMeasureData, setRainMeasureData] = useState<any>({}); // 강우, 측정 정보
const [mntrngsData, setMntrngsData] = useState<any[]>([]); // 수량/수질측정 정보
const [totalCount, setTotalCount] = useState<number>(0);
const [totalDetailCount, setTotalDetailCount] = useState<number>(0);
const [mntrngsData, setMntrngsData] = useState<any[]>([]); // 수량/수질 측정 정보
const [selectedRowIndex, setSelectedRowIndex] = useState<number>(-1);
const [curPage, setCurPage] = useState<number>(1);
const [curDetailPage, setCurDetailPage] = useState<number>(1);
const [isResetPage, setIsResetPage] = useState<boolean>(false);
const [isResetDetailPage, setIsResetDetailPage] = useState<boolean>(false);
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
const [curIdx, setCurIdx] = useState<number>(0);
// 강우, 측정 정보 API 호출 함수
const fetchRainMeasureData = async (chmbrXcnts: string, chmbrYdnts: string) => {
if (!chmbrXcnts || !chmbrYdnts) {
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { chmbrXcnts, chmbrYdnts });
return [];
}
try {
const queryParams = new URLSearchParams({
chmbrXcnts: chmbrXcnts,
chmbrYdnts: chmbrYdnts,
page: `${curPage - 1}`,
size: '3',
});
console.log('queryParams', queryParams.toString());
console.log(`추가 데이터 API 호출 시작: v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
console.log('추가 데이터 API 호출 성공:', result);
const processedDataArray: any[] = result.content.map((data: any) => {
// 🎯 formatDisplayData로 기본 포맷팅 적용
const formattedItem = formatDisplayData(data);
// 🎯 추가 데이터 조합
return {
...formattedItem,
flwmtrCombined: `${data.flwmtrMesureTpEtc || '-'} / ${data.flwmtrKnd || '-'}`,
};
});
setRainMeasureData(processedDataArray);
setTotalCount(result?.totalElements || 0);
} catch (error) {
console.error('추가 데이터 로딩 실패:', error);
return [];
}
};
// 수량/수질측정 정보 API 호출 함수
const fetchMntrngsData = async (adstDstrCd: string, manageNo: string) => {
if (!adstDstrCd || !manageNo) {
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { adstDstrCd, manageNo });
return [];
}
try {
const queryParams = new URLSearchParams({
page: `${curDetailPage - 1}`,
size: '3',
});
console.log(`SSC 추가 데이터 API 호출 시작: v1/onsemiro/swgRain?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`);
console.log('SSC 추가 데이터 API 호출 성공:', result);
// 각 아이템 전처리
const processedDataArray = result.content.map((data: any) => {
// 기본 포맷팅 적용
const formattedItem = formatDisplayData(data);
return {
...formattedItem,
};
});
console.log('processedDataArray', processedDataArray);
setMntrngsData(processedDataArray);
setTotalDetailCount(result?.totalElements || 0);
} catch (error) {
console.error('추가 데이터 로딩 실패:', error);
return [];
}
};
// 🎯 추가 데이터는 별도 useEffect로 비동기 로딩
useEffect(() => {
// 강우/측정 정보 데이터 호출
if (isMainSsc && chmbrXcnts && chmbrYdnts) {
fetchRainMeasureData(chmbrXcnts, chmbrYdnts)
}
}, [chmbrXcnts, chmbrYdnts]);
// console.log('featureData data received:', featureData); // 추가 데이터 확인용
// console.log('rainMeasureData received:', rainMeasureData); // 추가 데이터 확인용
const openModal = () => {
setIsModalOpen(true);
@@ -140,19 +46,6 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
}
}, [featureData]);
// featureData가 변경될 때 formData 초기화
useEffect(() => {
// showTable이 true일 때만 fetch (최초 렌더 방지)
setIsResetPage(false);
setIsResetDetailPage(true);
if (chmbrXcnts && chmbrYdnts) fetchRainMeasureData(chmbrXcnts, chmbrYdnts);
}, [curPage]);
// 페이지 변경 시마다 데이터 fetch
useEffect(() => {
if (chmbrXcnts && chmbrYdnts) fetchMntrngsData(chmbrXcnts, chmbrYdnts);
}, [curDetailPage]);
// 폼 데이터가 변경될 때 호출될 핸들러
const handleFormDataChange = (newFormData: any) => {
setFormData(newFormData);
@@ -169,39 +62,91 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
// 테이블 셀 클릭 핸들러 추가
const handleCellClick = async (index: number | undefined, headId: string) => {
if (index !== undefined && rainMeasureData) {
await fetchMntrngsData(rainMeasureData[index].adstDstrCd, rainMeasureData[index].manageNo);
const data = await fetchMntrngsData(rainMeasureData[index].adstDstrCd, rainMeasureData[index].manageNo);
setMntrngsData(data);
setSelectedRowIndex(index);
}
};
// 🎯 추가 데이터 API 호출 함수 (독립적으로 실행)
const fetchMntrngsData = useCallback(async (adstDstrCd: string, manageNo: string) => {
if (!adstDstrCd || !manageNo) {
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { adstDstrCd, manageNo });
return [];
}
try {
const queryParams = new URLSearchParams({
pageable: `{}`,
});
console.log(`SSC 추가 데이터 API 호출 시작: v1/onsemiro/swgRain?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`);
console.log('SSC 추가 데이터 API 호출 성공:', result);
// 🎯 result가 페이지네이션 객체인 경우 content 배열 추출
let dataArray: any[] = [];
if (result && typeof result === 'object' && 'content' in result && Array.isArray(result.content)) {
dataArray = result.content;
} else if (Array.isArray(result)) {
dataArray = result;
} else {
console.warn('예상치 못한 API 응답 형식:', result);
return [];
}
// 🎯 각 아이템을 전처리하여 반환
const processedDataArray = dataArray.map((data: any) => {
// 🎯 formatDisplayData로 기본 포맷팅 적용
const formattedItem = formatDisplayData(data);
// 🎯 추가 데이터 조합
return {
...formattedItem,
};
});
console.log('processedDataArray', processedDataArray);
return processedDataArray;
} catch (error) {
console.error('추가 데이터 로딩 실패:', error);
return [];
}
}, []);
const renderModalBody = () => (
<div className='grid grid-cols-1 gap-4 p-4'>
{/* 강우정보 테이블 */}
<UiTable
headName='강우정보'
tableData={rainMeasureData}
tableData={Array.isArray(rainMeasureData) ? rainMeasureData : []}
headlist={untrtSwgRainCol3}
pageSize={3}
total={0}
pageSize={10}
total={Array.isArray(rainMeasureData) ? rainMeasureData.length : 0}
cellClick={handleCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
index={curIdx}
onPageChange={function (page: number): void {
console.log('Rain data page change:', page);
}}
/>
{/* 측정정보 테이블 */}
<UiTable
headName='측정정보'
tableData={rainMeasureData}
tableData={Array.isArray(rainMeasureData) ? rainMeasureData : []}
headlist={untrtSwgRainCol4}
pageSize={3}
total={totalCount}
pageSize={10}
total={Array.isArray(rainMeasureData) ? rainMeasureData.length : 0}
cellClick={handleCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
index={curIdx}
// onPageChange={setCurPage}
onPageChange={function (page: number): void {
console.log('Rain data page change:', page);
}}
resetPageNo={false}
// index={curPage}
>
{/* 커스텀 헤더 */}
<TableRow>
@@ -223,12 +168,14 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
{/* 수량/수질측정 정보 테이블 */}
<UiTable
headName='수량/수질측정 정보'
tableData={mntrngsData}
tableData={Array.isArray(mntrngsData) ? mntrngsData : []}
headlist={untrtSwgRainCol5}
pageSize={3}
total={totalDetailCount}
pageSize={10}
total={Array.isArray(mntrngsData) ? mntrngsData.length : 0}
cellClick={undefined}
onPageChange={setCurDetailPage}
onPageChange={function (page: number): void {
console.log('Quality data page change:', page);
}}
/>
</div>
)
@@ -162,7 +162,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
<span className="text-2xl text-red-600 font-bold">● 침입수량 산정결과</span>
<div className="flex items-center mt-2">
<span className="ml-5 text-black text-xl">침입수량 : </span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold">{inftwtQty}</span>
<span className="w-[35px] inline-block text-right text-black text-xl font-bold">{inftwtQty}</span>
<span className="ml-2 text-black text-xl">m³/d</span>
</div>
</div>
@@ -170,7 +170,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
{/* 차트 */}
<div className="h-[90%] bg-white text-3xl">
<MainChart chartConfig={chartConfig} chartForm={chartForm} chartData={chartData} chartTitle={'침입수량 그래프'}
yFieldText2="" yFieldText="유량(m³/h)"/>
yFieldText2="시간" yFieldText="유량(m³/h)"/>
</div>
</div>
{popupOpen && (
@@ -161,17 +161,17 @@ const RdiiChart = ({ pplMngNo }: ModalOpenProp) => {
<span className="text-2xl text-red-600 font-bold">● 강우유입수량 분석결과</span>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">평균RDII : </span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {rdiiQty}</span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {rdiiQty}</span>
<span className="ml-2 text-black"> m³/d</span>
</div>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">적용강우량 : </span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {rainTotal}</span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {rainTotal}</span>
<span className="ml-2 text-black"> mm</span>
</div>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">강우량대비RDII : </span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {totalVolume}</span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {totalVolume}</span>
<span className="ml-2 text-black"> m³/mm</span>
</div>
</div>
@@ -31,14 +31,6 @@ const isYear = (value: string): boolean => {
return /^[0-9]{4}년$/.test(value);
};
export const reportGubuns = [{val: '0', text: '전체'}, {val: '1', text: '보고서'}
, {val: '2', text: '요약보고서'} , {val: '3', text: '부록'}, {val: '4', text: '기타'}];
/**
* Flatten a hierarchical folder structure into a flat array.
* @param data - The hierarchical folder data to flatten.
* @returns An array of flattened folders with their paths and levels.
*/
export function flattenFolders(data: Folder[]): FlattenedFolder[] {
const result: FlattenedFolder[] = [];
const exceptNodeNm = ["부분","통합","전체"];
@@ -80,10 +72,15 @@ export function flattenFolders(data: Folder[]): FlattenedFolder[] {
}
data.forEach((root) => traverse(root, {}, 0));
console.log(result.slice(0, 10));
return result;
}
export const getDcTree = async (clsfSystmNm:string) => {
//const cityName = encodeURIComponent(clsfSystmNm);
const queryString = 'clsfSystmNm='+clsfSystmNm;
console.log("getDcTree queryString:", queryString);
//const result = await getDcData(`/api/v1/dc/clsf${queryString ? `?${queryString}` : ''}`);
const result = await getDcData("/api/v1/dc/clsf?clsfSystmNm=" + clsfSystmNm);
return result;
};
@@ -113,8 +110,13 @@ export const addFileName = async (data:FlattenedFolder[]) => {
data.map(async (item) => {
const filenameArr:ReportDataFile[] = await getDcFile(String(item.clsfSystmSn));
const f = filenameArr[0];
//console.log("clsfSystmSn:", item.clsfSystmSn, "f:", f);
const result = {...item, fileName:f?.fileTitle, regDate:f?.regDt, fileSn:f?.fileSn, filePath:f?.filePath};
// if (f !== undefined && f.fileSn !== "") {
// const fprcs = await getDcFileprcs(f?.fileSn);
// if (fprcs.length>0)
// result.filePath = fprcs[0].filePath;
// }
return result;
})
);
@@ -122,6 +124,7 @@ export const addFileName = async (data:FlattenedFolder[]) => {
}
export const getDcFileprcs = async (fileSn:string) => {
const queryString = 'fileSn='+fileSn;
console.log("getDcTree queryString:", queryString);
const result = await getDcData(`/api/v1/dc/fileprcs${queryString ? `?${queryString}` : ''}`);
return result;
};
@@ -148,6 +151,9 @@ export const fileDownload = (data:Blob, fileName:string) => { // Blob데이터
window.URL.revokeObjectURL(url);
}
export const getFileDownload = async (fileSn:string, fileName:string, filePath:string) => {
//const fileprcsData = await getDcFileprcs(fileSn); // filePath 조회
//if (fileprcsData?.length === 0 ) { alert("filePath 조회 오류"); }
//if (fileprcsData[0].filePath === "") alert("filePath 정보 없으므로 다운로드 불가");
if (filePath === "") alert("filePath 정보 없으므로 다운로드 불가:filesn"+ fileSn);
const blobData = await getDcFileDownload(filePath); // 실제 다운로드 API
fileDownload(blobData, fileName);
@@ -159,13 +165,12 @@ export const getCityCd = async (): Promise<SelectDataType[]> => {
if (!response.ok) throw new Error(`시도 데이터 오류: ${response.status}`);
const res = await response.json();
const city = res.data;
let citys:SelectDataType[] = city.map((item: {adstDstrCd:string, sido:string}) => ({
const cityCd = city.map((item: any) => ({
val: item.adstDstrCd,
text: item.sido,
}));
citys = citys.sort((a:SelectDataType, b:SelectDataType) => a.text.localeCompare(b.text));
citys.unshift({ val: '0', text: '전체' });
return citys;
cityCd.unshift({ val: '0', text: '전체' });
return cityCd;
} catch (error) {
console.error('시도 데이터를 가져오는데 실패했습니다:', error);
return [{ val: '0', text: '전체', sido: '0' }];
@@ -181,9 +186,9 @@ export const useSggCd = () => {
if (result) {
setData(result);
}
console.log("useSggCd호출");
};
fetch();
console.log("useSggCd호출");
}, []);
return data;
};
@@ -195,7 +200,7 @@ export const getSggCd = async (): Promise<SelectDataType[]> => {
if (!response.ok) throw new Error(`시군구 데이터 오류: ${response.status}`);
const res = await response.json();
const sgg = res.data;
const sggCd = sgg.map((item: {adstDstrCd:string, sido:string, gugun:string}) => ({
const sggCd = sgg.map((item: any) => ({
val: item.adstDstrCd,
sido: item.sido,
text: item.gugun,
@@ -217,9 +222,9 @@ export const useCityCd = () => {
if (result) {
setData(result);
}
console.log("useCityCd호출");
};
fetch();
console.log("useCityCd호출");
}, []);
return data;
};
@@ -5,13 +5,13 @@ import { VerticalTable } from "@/components/ui/verticalTable";
import { useGisContext } from "@common/business_components/ui/map/Gis";
import { Button } from "@common/components/ui";
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
import { getLayerContentComponent } from "../common";
import { SwtrmtFcltCol, SwtrmtFcltCol2, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, MsSwagePplCol2, ExclnSewagePumpCol, ExclnSewagePumpCol2, DrtwSewagePumpCol, DrtwSewagePumpCol2, MsSwageMhlCol, MsSwageMhlCol2, stofcbrCol, stofcbrCol2, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "../common/table";
import InfilChart from './chart/infilChart';
import RdiiChart from './chart/rdiiChart';
import { useInfilChartModalStore, useRdiiChartModalStore } from "./chartModalStore";
import { getLayerContentComponent } from "./components/common";
import { SwtrmtFcltCol, SwtrmtFcltCol2, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, MsSwagePplCol2, ExclnSewagePumpCol, ExclnSewagePumpCol2, DrtwSewagePumpCol, DrtwSewagePumpCol2, MsSwageMhlCol, MsSwageMhlCol2, stofcbrCol, stofcbrCol2, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "./components/common/table";
import InfilChart from './components/popupComponent/chart/infilChart';
import RdiiChart from './components/popupComponent/chart/rdiiChart';
import { useInfilChartModalStore, useRdiiChartModalStore } from "./components/popupComponent/chartModalStore";
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
import { codeMapper } from "../common/codeMapper";
import { codeMapper } from "./components/common/codeMapper";
import { searchUpperPpls } from '@common/business_components/ui/map/Gis';
import LoadingOverlay from '@/components/ui/LoadingBar';
@@ -33,10 +33,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
// 🎯 InfilChart 및 RdiiChart 관련 상태 추가
const { setIsOpen: setIsModalInfil } = useInfilChartModalStore();
const { setIsOpen: setIsModalRdii } = useRdiiChartModalStore();
const [curPage, setCurPage] = useState(1); // 현재 페이지 상태
const [isClicked, setIsClicked] = useState(true); // 클릭 여부 상태
const [isLoading, setIsLoading] = useState(false); // 로딩 상태
const [chmbrXcnts, setChmbrXcnts] = useState(); // 로딩 상태
const [chmbrYdnts, setChmbrYdnts] = useState(); // 로딩 상태
// 🎯 관로관리번호 추출
const pplMngNo = featureData?.values_?.fclt_mng_no || "";
@@ -264,9 +263,18 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
data: { ...processedFormattedData }
}));
setChmbrXcnts(data.chmbr_xcnts);
setChmbrYdnts(data.chmbr_ydnts);
// 강우/측정 정보 데이터 호출
if (tableData?.chmbr_xcnts && tableData?.chmbr_ydnts) {
fetchRainMeasureData(tableData.chmbr_xcnts, tableData.chmbr_ydnts)
.then(response => {
console.log('additionalResponse', response);
setRainMeasureData(response || []);
})
.catch(error => {
console.error('추가 데이터 로딩 실패:', error);
setRainMeasureData([]);
});
}
break;
default:
break;
@@ -309,6 +317,76 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
fetchData();
}, [featureId, processedData]);
// 🎯 추가 데이터 API 호출 함수
const fetchRainMeasureData = useCallback(async (chmbrXcnts: string, chmbrYdnts: string) => {
if (!chmbrXcnts || !chmbrYdnts) {
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { chmbrXcnts, chmbrYdnts });
return [];
}
try {
const queryParams = new URLSearchParams({
chmbrXcnts: chmbrXcnts,
chmbrYdnts: chmbrYdnts,
pageable: `{}`,
});
console.log(`추가 데이터 API 호출 시작: v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
console.log('추가 데이터 API 호출 성공:', result);
// 🎯 result가 페이지네이션 객체인 경우 content 배열 추출
let dataArray: any[] = [];
if (result && typeof result === 'object' && 'content' in result && Array.isArray(result.content)) {
dataArray = result.content;
} else if (Array.isArray(result)) {
dataArray = result;
} else {
console.warn('예상치 못한 API 응답 형식:', result);
return [];
}
// 🎯 각 아이템을 전처리하여 반환
const processedDataArray = dataArray.map((data: any) => {
// 🎯 formatDisplayData로 기본 포맷팅 적용
const formattedItem = formatDisplayData(data);
// 🎯 추가 데이터 조합
return {
...formattedItem,
flwmtrCombined: `${data.flwmtrMesureTpEtc || '-'} / ${data.flwmtrKnd || '-'}`,
};
});
return processedDataArray;
} catch (error) {
console.error('추가 데이터 로딩 실패:', error);
return [];
}
}, []);
// 🎯 추가 데이터는 별도 useEffect로 비동기 로딩
useEffect(() => {
if (layerNm === '중점우수토실' && featureData?.values_) {
const data = featureData.values_;
if (data?.chmbr_xcnts && data?.chmbr_ydnts) {
// 🎯 추가 데이터를 비동기로 로딩 (UI 블로킹 없음)
fetchRainMeasureData(data.chmbr_xcnts, data.chmbr_ydnts)
.then(response => {
console.log('추가 데이터 로딩 완료:', response);
setRainMeasureData(response || []);
})
.catch(error => {
console.error('추가 데이터 최종 로딩 실패:', error);
setRainMeasureData([]);
});
}
}
}, [layerNm, featureData?.values_, fetchRainMeasureData]);
// 저장 시 모달 띄우기
const handleSaveClick = () => {
setIsModalOpen(true); // 모달 열기
@@ -404,47 +482,45 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
</>
)} 정보 <br />관리번호 : {layerSpecificNm}
</h3>
</div>
<div className="flex items-center space-x-3">
{/* 🎯 하수관로일 때만 Infil/RDII 버튼 표시 */}
{layerNm === '하수관로' && (
<>
<Button onClick={() => setIsModalInfil(true)}
className="py-1 text-xl text-blue-600 border border-blue-600 rounded hover:bg-gray-700"
color="white"
size="sm"
>
침입수분석
</Button>
<Button onClick={() => setIsModalRdii(true)}
className="py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700 mr-4"
color="white"
size="sm"
>
RDII분석
</Button>
</>
)}
{layerNm === '하수맨홀' && (
<>
<Button
color="white"
className="px-2 py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700 mr-4"
onClick={() => {
<div className="flex items-center space-x-3">
{/* 🎯 하수관로일 때만 Infil/RDII 버튼 표시 */}
{layerNm === '하수관로' && (
<>
<Button onClick={() => setIsModalInfil(true)}
className="py-1 text-xl text-blue-600 border border-blue-600 rounded hover:bg-gray-700"
color="white"
size="sm"
>
침입수분석
</Button>
<Button onClick={() => setIsModalRdii(true)}
className="py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700"
color="white"
size="sm"
>
RDII분석
</Button>
</>
)}
{layerNm === '하수맨홀' && (
<>
<Button onClick={() => {
setIsLoading(true);
searchUpperPpls(layerSpecificNm).finally(() => setIsLoading(false));
}}
>
상류관로 보기
</Button>
</>
)}
className="px-2 py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700"
color="white"
>
상류관로 보기
</Button>
</>
)}
</div>
</div>
<Button
onClick={onClose}
// className="text-white hover:text-gray-300 focus:outline-none"
className="flex items-center space-x-4 text-white hover:text-gray-300 focus:outline-none"
// className="absolute top-8 right-4 text-white hover:text-gray-300 focus:outline-none"
className="absolute top-8 right-4 text-white hover:text-gray-300 focus:outline-none"
size="xs"
>
✕
@@ -477,10 +553,8 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
featureData={fetchData}
isMainSsc={isMainSsc}
isDrtwSewagePump={isDrtwSewagePump}
// rainMeasureData={rainMeasureData}
rainMeasureData={rainMeasureData}
onSaveClick={handleSaveClick}
chmbrXcnts={chmbrXcnts}
chmbrYdnts={chmbrYdnts}
/>
}
</div>
+1 -11
View File
@@ -5,9 +5,7 @@ import { getData } from "../../components/lib/api";
import { useCallback, useEffect, useRef, useState } from "react";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import SearchModal from "./searchModal/searchModal";
import FeatureClickEventPopup from "./components/popupComponent/featureClickEventPopup";
import useStore from "../../store/useStore";
import { SearchBar } from "./searchBar/searchBar";
import FeatureClickEventPopup from "./featureClickEventPopup";
// 타입 정의 추가
export type LyrStngProps = {
@@ -40,13 +38,6 @@ const Map = () => {
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
const { fetchCtpvData, fetchSggData } = useStore();
// 시도, 시군구 호출
useEffect(() => {
fetchCtpvData();
fetchSggData();
}, [fetchCtpvData, fetchSggData]);
const fetchData = async () => {
try {
@@ -139,7 +130,6 @@ const Map = () => {
isOpen={isOpen}
isSearchModalOpen={isSearchModalOpen}
onCheckedLayersChange={undefined}
searchBar={SearchBar}
/>
</div>
);
@@ -1,83 +0,0 @@
"use client";
import {
SearchDiv,
SearchFormLeft,
SelectBox,
type SelectDataType,
} from "@common/business_components/ui";
import { useCallback, useEffect, useState } from "react";
export function SearchBar() {
const [sidoValue, setSidoValue] = useState<string>("");
const [sigunValue, setSigunValue] = useState<string>("");
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([
{ text: "시도 선택", val: "0" },
]);
const initializeSigunData = useCallback((sidoCd: string) => {
if (sidoCd === "0") {
setSigunValue("0");
setFilteredSigunData([{ text: "시도 선택", val: "0" }]);
} else {
const newFilteredData = [
{ text: "데이터", val: "0" },
// ...Common.selectSigunData.filter(
// (item: SelectDataType) => item.val.substring(0, 2) === sidoCd,
// ),
];
setSigunValue("0");
setFilteredSigunData(newFilteredData);
}
}, []);
const onSelectValue = useCallback(
(val: string, type: string) => {
switch (type) {
case "ctpvCd":
initializeSigunData(val);
setSidoValue(val);
break;
case "sggCd":
setSigunValue(val);
}
},
[initializeSigunData],
);
return (
<>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<div className="card card-border flex">
<div className="col-span-10 flex flex-row">
<SelectBox
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
label="시도"
selectArray={/* Common.selectSidoData || */ []}
onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")}
value={sidoValue || /* Common.selectSidoData[0]?.val || */ ""}
/>
<SelectBox
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
label="시군구"
selectArray={filteredSigunData || []}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
value={sigunValue}
/>
<SelectBox
className="mr-3 w-[250px]"
selectClass="rounded-lg bg-white"
labelClass="w-[200px]"
label="하수처리시설명"
selectArray={filteredSigunData || []}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
value={sigunValue}
/>
</div>
</div>
</div>
</div>
</>
);
}
@@ -39,9 +39,7 @@ interface BasicTabProps {
// setTableCount?: (count: number) => void;
setBasicType: (type: string) => void;
setCity: (city: number) => void;
setCtpvName: (name: string) => void;
setSgg: (sgg: number) => void;
setSggName: (name: string) => void;
setYearFilter: (filter: { start: string; end: string }) => void;
setStart1: (value: string) => void;
setStart2: (value: string) => void;
@@ -70,9 +68,7 @@ const BasicTab: React.FC<BasicTabProps> = ({
// setTableCount,
setBasicType,
setCity,
setCtpvName,
setSgg,
setSggName,
setYearFilter,
setStart1,
setStart2,
@@ -82,15 +78,14 @@ const BasicTab: React.FC<BasicTabProps> = ({
setVar2,
}) => {
return (
<div className="relative border rounded-lg p-5 w-full h-[10vh]">
<div className="relative border rounded-lg p-6 w-full h-[10vh]">
{/* 구분 */}
<div className="mb-3 flex items-center justify-between gap-4">
<div className="flex items-center">
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">구분</Label>
<SelectBox
className="w-[150px] mr-3"
selectClass="rounded-lg bg-white"
label=""
label="구분"
selectArray={BASIC_TYPES}
onSelectValue={(value: string | number) =>
setBasicType(String(value))
@@ -106,16 +101,12 @@ const BasicTab: React.FC<BasicTabProps> = ({
var1={var1}
var2={var2}
start1={start1}
start2={start2}
end1={end1}
end2={end2}
yearFilter={yearFilter}
setVar1={setVar1}
setVar2={setVar2}
setStart1={setStart1}
setStart2={setStart2}
setEnd1={setEnd1}
setEnd2={setEnd2}
setYearFilter={setYearFilter}
handleSearch={handleSearch}
/>
@@ -128,18 +119,12 @@ const BasicTab: React.FC<BasicTabProps> = ({
start2={start2}
end1={end1}
end2={end2}
city={city}
sgg={sgg}
yearFilter={yearFilter}
setVar1={setVar1}
setStart1={setStart1}
setStart2={setStart2}
setEnd1={setEnd1}
setEnd2={setEnd2}
setCity={setCity}
setCtpvName={setCtpvName}
setSgg={setSgg}
setSggName={setSggName}
setYearFilter={setYearFilter}
handleSearch={handleSearch}
/>
@@ -12,9 +12,11 @@ import React from 'react';
// { val: "inspection", text: "점검 및 진단" },
// ];
export const WORK_TYPES = [
{ val: "['200', '201', '204']", text: "보수 및 갱신" },
{ val: "['100']", text: "점검 및 진단" },
{ val: "['203']", text: "청소 및 준설" },
{ val: "200", text: "보수 및 갱신(개대체)" },
{ val: "201", text: "보수 및 갱신(유지보수)" },
{ val: "204", text: "보수 및 갱신(단순보수)" },
{ val: "100", text: "점검 및 진단" },
{ val: "203", text: "청소 및 준설" },
];
// const BIZ_SE_CD = useBizByFcltStore(state => state.BIZ_SE_CD);
export const BIZ_SE_CD = [
@@ -111,13 +113,12 @@ const OperationTab: React.FC<OperationTabProps> = ({
setYearFilter,
}) => {
return (
<div className="relative flex flex-col border rounded-lg p-5 w-full h-[10vh]">
<div className="relative flex flex-col border rounded-lg p-6 w-full h-[10vh]">
<div className="flex items-center mb-3">
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">업무구분</Label>
<SelectBox
className="w-80 mr-8"
selectClass="rounded-lg bg-white text-xl"
label=""
label="업무구분"
selectArray={WORK_TYPES.map((w) => ({
val: w.val,
text: w.text,
@@ -128,18 +129,12 @@ const OperationTab: React.FC<OperationTabProps> = ({
/>
</div>
<div className="flex items-center mb-6">
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">사업명</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">사업명</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center mr-8"
className="w-[100px] !text-xl placeholder:text-center mr-4"
placeholder="입력"
value={var1}
onChange={(e) => { setVar1(e.target.value); }}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
<YearRangeSelectBox
start={yearFilter.start}
@@ -148,11 +143,10 @@ const OperationTab: React.FC<OperationTabProps> = ({
startLabel="수행기간"
endLabel=""
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">사업 유형</Label>
<SelectBox
className="w-60 mr-8"
className="ml-8 w-60 mr-8"
selectClass="rounded-lg bg-white text-xl"
label=""
label="사업 유형"
selectArray={BIZ_TY_CD_SELECT_ARRAY}
value={var2}
onSelectValue={(val) => {
@@ -1,15 +1,14 @@
'use client';
import React, { useEffect, useState } from 'react';
import { Button, Label } from '@common/components';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { SelectBox, UiTable } from '@common/business_components/ui';
import LoadingOverlay from '@/components/ui/LoadingBar';
import { addFileName, flattenFolders, getFileDownload, useCityCd, useDcTree, useSggCd, reportGubuns } from './searchModalReportApi';
import { SelectBox } from '@common/business_components/ui';
import { Button, Input } from '@common/components';
import React from 'react';
//import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi';
import { type SelectDataType } from '../commonStore';
import { useCityCd, useSggCd } from '../components/searchModalReportApi';
// import { useBizByFcltStore } from "../../../store/StoreProvider";
// 하수도정비 기본계획 보고서
// // 하수도정비 기본계획 보고서
export const reportTableHeadlist = [
{ id: "no", title: "NO" },
{ id: "sido", title: "시도" },
@@ -24,176 +23,79 @@ export const reportTableHeadlist = [
interface BasicTabProps {
open?: boolean;
gubun: string;
sidos: SelectDataType[];
ctpvCd: string | number;
sigungu: string;
filteredSiguns: SelectDataType[];
yearFilter: { start: string; end: string; };
handleSearch: () => void;
handleCtpvCdChange: (val: string | number) => void;
// onOpenChange?: (open: boolean) => void;
// onFeatureSelect?: (row: any) => void;
// setTableData?: (data: any[]) => void;
// setTableCount?: (count: number) => void;
setYearFilter: (filter: { start: string; end: string }) => void;
setGubun: (gubun: string) => void;
setSigungu: (sigungu: string) => void;
}
const ReportTab: React.FC<BasicTabProps> = ({ open }) => {
const [isLoading, setIsLoading] = useState(false);
const [isResetPage, setIsResetPage] = useState<boolean>(false);
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
const [showTable, setShowTable] = useState(false);
const [tableData, setTableData] = useState<any[]>([]);
const [tableCount, setTableCount] = useState(0);
const [curPage, setCurPage] = useState(1);
const [yearFilter, setYearFilter] = useState({ start: "", end: "" });
const [ctpvCd, setCtpvCd] = useState('0'); // 하수정비기본계획 report
const [sigungu, setSigungu] = useState('0'); // 하수정비기본계획 report
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [reportGubun, setReportGubun] = useState("0"); // 하수정비기본계획 report
// 하수정비기본계획 report
const sidos = useCityCd();
const siguns = useSggCd();
const reportOriginData = useDcTree(""); //:Folder[]
const dynamicHeadlist: { id: string, title: string }[] = reportTableHeadlist;
useEffect(() => {
// filterParams 초기화
setCtpvCd('0');
setSigungu('0');
setReportGubun('0');
setYearFilter({ start: "", end: "" });
setShowTable(false);
setTableData([]);
setTableCount(0);
setCurPage(1); // 페이지를 1로 초기화
setIsResetPage(true); // 페이지를 초기화
setIsResetSelection(true); // 선택 초기화
}, [open]);
// 페이지 변경 시마다 데이터 fetch
useEffect(() => {
// showTable이 true일 때만 fetch (최초 렌더 방지)
setIsResetPage(false);
setIsResetSelection(true); // 선택 초기화
if (showTable) fetchFilteredData();
}, [curPage]);
const handleCtpvCdChange = (val: string | number) => { // 하수도정비기본계획.시도
const sidoOption = sidos.find((n) => n.val === val);
setCtpvCd(String(val));
if (val !== '0') {
const filterSiguns = siguns.filter(item => item.sido === sidoOption?.text);
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ start: "", end: "", });
}
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
const handleSearch = () => {
setCurPage(1); // 페이지를 1로 초기화
fetchFilteredData();
setIsResetPage(true); // 페이지를 초기화
setIsResetSelection(false); // 선택 초기화
setShowTable(true);
};
// 하수도정비기본계획 테이블 cellClick 핸들러
const handleReportCellClick = (index: number | undefined ) => {
console.log(index);
if (typeof index === "number" && tableData[index]) {
const reportData = tableData[index];
const fileName = reportData.fileName;
const filePath = reportData.filePath;
if (reportData.fileSn !== "") {
getFileDownload(reportData.fileSn, fileName, filePath);
}
}
};
// 검색 API 호출 함수
const fetchFilteredData = async () => {
setIsLoading(true); // 로딩 시작
setIsResetSelection(true); // 선택 초기화
try {
//const reportOriginData = await getDcTree('경기도');
const reportData = flattenFolders(reportOriginData);
let filterReportData = reportData;
if (ctpvCd !== "0") { // 시도검색
const sidoOption = sidos.find((n) => n.val === ctpvCd);
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text);
}
if (sigungu !== "0") { // 시군구검색
const sigunguOption = filteredSiguns.find((n) => n.val === sigungu);
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.text);
}
if (reportGubun !== "0") { // 보고서구분검색
const reportGubunOption = reportGubuns.find((n) => n.val === reportGubun);
filterReportData = filterReportData.filter(item => item.reportGubun === reportGubunOption?.text);
}
if (yearFilter.start != "" && yearFilter.end == "") //승인년도검색
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" : null);
if (yearFilter.start == "" && yearFilter.end != "")
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear <= yearFilter.end + "년" : null);
if (yearFilter.start != "" && yearFilter.end != "") {
filterReportData = filterReportData.filter(item => {
return (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" && item.approvalYear <= yearFilter.end + "년" : null;
});
}
if (gubun !== "") { // 구분검색
filterReportData = filterReportData.filter(item => (item.plantZoneGugun) ? String(item.plantZoneGugun).includes(String(gubun)) : null);
}
console.log('report count:', filterReportData.length);
setTableCount(filterReportData.length || 0);
filterReportData = filterReportData.slice((curPage - 1) * 10, curPage * 10); // paging
filterReportData = filterReportData?.map((item, index) => ({ ...item, no: (curPage - 1) * 10 + index + 1 }));
//const fileList = await getDcFile("CLS20250530000041");
addFileName(filterReportData).then(data => {
filterReportData = data;
setTableData(filterReportData || []);
});
setTableData(filterReportData || []);
setShowTable(true);
} catch (err) {
console.error('API ERROR:', err);
setTableData([]);
} finally {
setIsLoading(false); // 로딩 종료
}
};
const ReportTab: React.FC<BasicTabProps> = ({
open,
gubun,
sidos,
ctpvCd,
sigungu,
filteredSiguns = [{ val: '0', text: '전체', sido: '0' }],
yearFilter,
handleSearch,
handleCtpvCdChange,
// onOpenChange,
// onFeatureSelect,
// setTableData,
// setTableCount,
setYearFilter,
setGubun,
setSigungu,
}) => {
return (
<>
<div className="relative flex flex-col border rounded-lg p-5 w-full h-[10vh]">
<div className="relative flex flex-col border rounded-lg p-6 w-full h-[10vh]">
<div className="flex items-center mb-3">
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시도</Label>
<SelectBox className="w-60 mr-8"
<SelectBox
className="w-[150px] mr-8"
selectClass="rounded-lg bg-white"
label="" selectArray={sidos}
value={ctpvCd} onSelectValue={handleCtpvCdChange}
label="시도"
selectArray={sidos}
value={ctpvCd}
onSelectValue={handleCtpvCdChange}
selectContentClass="z-[101]"
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시군구</Label>
<SelectBox className="w-48"
<SelectBox
className="w-48"
selectClass="w-48 rounded-lg bg-white truncate"
label="" selectArray={filteredSiguns}
value={sigungu} onSelectValue={val => setSigungu(String(val))}
label="시군구"
selectArray={filteredSiguns}
value={sigungu}
onSelectValue={val => setSigungu(String(val))}
selectContentClass="z-[101]"
/>
</div>
<div className="flex items-center mb-6">
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">보고서 구분</Label>
<SelectBox className="w-44 mr-8"
selectClass="rounded-lg bg-white"
label="" selectArray={[...reportGubuns]}
value={reportGubun} onSelectValue={val => setReportGubun(String(val))}
selectContentClass="z-[101]" labelClass='whitespace-nowrap text-xl text-gray-600 pr-2'
<label className="inline-block w-auto whitespace-nowrap text-xl text-gray-600 mr-2">구분</label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={gubun}
onChange={(e) => { setGubun(e.target.value); }}
/>
{/* 승인년도 필터 */}
<YearRangeSelectBox start={yearFilter.start} end={yearFilter.end}
<YearRangeSelectBox
start={yearFilter.start}
end={yearFilter.end}
onChange={range => setYearFilter({ ...yearFilter, start: range.start, end: range.end })}
startLabel="승인년도" endLabel=""
startLabel="승인년도"
endLabel=""
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -201,28 +103,6 @@ const ReportTab: React.FC<BasicTabProps> = ({ open }) => {
</div>
</div>
</div>
<div className="h-[79vh] w-full overflow-hidden rounded-lg border">
{/* 테이블2 영역 (가로/세로 스크롤 가능) */}
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={(() => {
return (<>조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={tableData}
headlist={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={handleReportCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
/>
</div>
</div>
</>
);
};
@@ -3,8 +3,11 @@ import { UiModal, UITab, UiTable } from '@common/business_components/ui';
import axios from 'axios';
import React, { useEffect, useMemo, useState } from 'react';
import { ExclnSewagePumpCol2, MsSwageMhlCol2, MsSwagePplCol2, stofcbrCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2 } from '../components/common/table';
//import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi';
import { type SelectDataType } from '../commonStore';
import { MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_USE_CODES, MS_SWAGE_MHL_CODES } from '../components/common/table';
import { addFileName, flattenFolders, getFileDownload, useCityCd, useDcTree, useSggCd } from '../components/searchModalReportApi';
// import { useBizByFcltStore } from "../../../store/StoreProvider";
import { getData } from "@/components/lib/api";
import BasicTab, { BASIC_TYPES } from './basicTab';
import OperationTab, { BIZ_TY_CD, operationCleaningTableHeadlist, operationInspectionTableHeadlist, operationMaintenanceTableHeadlist, operationTableHeadlist, WORK_TYPES } from './operationTab';
@@ -63,14 +66,11 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
const [isResetDetailSelection, setIsResetDetailSelection] = useState<boolean>(false);
const [detailBizId, setDetailBizId] = useState(0);
const [city, setCity] = useState<number>(0);
const [ctpvName, setCtpvName] = useState<string>('');
const [sgg, setSgg] = useState<number>(0);
const [sggName, setSggName] = useState<string>('');
const [ctpvCd, setCtpvCd] = useState('0'); // 하수정비기본계획 report
const [sigungu, setSigungu] = useState('0'); // 하수정비기본계획 report
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [reportGubun, setReportGubun] = useState("0"); // 하수정비기본계획 report
const [city, setCity] = useState(0);
const [sgg, setSgg] = useState(0);
const [ctpvCd, setCtpvCd] = useState('0');
const [sigungu, setSigungu] = useState('0');
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [start1, setStart1] = useState("");
const [start2, setStart2] = useState("");
const [end1, setEnd1] = useState("");
@@ -83,6 +83,9 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [yearFilter, setYearFilter] = useState({ start: "", end: "" });
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
const sidos = useCityCd();
const siguns = useSggCd();
const reportOriginData = useDcTree(""); //:Folder[]
// 오늘 날짜 구하기
const today = new Date();
@@ -102,15 +105,18 @@ const SearchModal: React.FC<SearchModalProps> = ({
return [];
}
if (activeTab === 'operation') return operationTableHeadlist;
if (activeTab === 'report') return reportTableHeadlist;
return [];
}, [activeTab, basicType, workType]);
const dynamicHeadlist2: { id: string, title: string }[] = useMemo(() => {
if (activeTab === 'operation') {
if (workType === WORK_TYPES[0]?.val) return operationMaintenanceTableHeadlist;
if (workType === WORK_TYPES[1]?.val) return operationCleaningTableHeadlist;
if (workType === WORK_TYPES[2]?.val) return operationInspectionTableHeadlist;
if (workType === '200') return operationMaintenanceTableHeadlist;
if (workType === '201') return operationMaintenanceTableHeadlist;
if (workType === '204') return operationMaintenanceTableHeadlist;
if (workType === '100') return operationCleaningTableHeadlist;
if (workType === '203') return operationInspectionTableHeadlist;
}
return [];
@@ -128,6 +134,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
setVar4("");
setCity(0);
setSgg(0);
setCtpvCd('0');
setSigungu('0');
setYearFilter({
start: "",
end: "",
@@ -179,7 +187,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
setIsLoading(true); // 로딩 시작
setIsResetSelection(true); // 선택 초기화
setIsResetDetailSelection(true); // 선택 초기화
try {
let cqlFilters: string[] = [];
if (activeTab === 'basic') {
@@ -247,8 +255,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
RequestDTO.fromflfmtEndYmd = startDate;
RequestDTO.toflfmtEndYmd = endDate;
// JSON.parse 사용으로 문자열 -> 배열 변환
RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"'));
RequestDTO.bizSeCd = workType;
const params = new URLSearchParams(RequestDTO).toString();
@@ -263,7 +271,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const matched = BIZ_TY_CD.find(code => code.lwpoCd === item.bizTyCd);
return {
...formattedItem,
rowNumber: (curPage - 1) * 5 + index + 1, // 1부터 시작하는 일련번호 추가
rowNumber: (curPage - 1) * 4 + index + 1, // 1부터 시작하는 일련번호 추가
bizTyCd: matched ? matched.lwpoCdNm : item.bizTyCd,
};
});
@@ -272,6 +280,41 @@ const SearchModal: React.FC<SearchModalProps> = ({
setTableCount(res.totalElements || 0);
setDetailTableData([]);
setDetailTableCount(0);
} else if (activeTab === 'report') {
//const reportOriginData = await getDcTree('경기도');
const reportData = flattenFolders(reportOriginData);
let filterReportData = reportData;
if (ctpvCd !== "0") { // 시도검색
const sidoOption = sidos.find((n) => n.val === ctpvCd);
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text);
}
if (sigungu !== "0") { // 시군구검색
const sigunguOption = filteredSiguns.find((n) => n.val === sigungu);
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.text);
}
if (yearFilter.start != "" && yearFilter.end == "") //승인년도검색
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" : null);
if (yearFilter.start == "" && yearFilter.end != "")
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear <= yearFilter.end + "년" : null);
if (yearFilter.start != "" && yearFilter.end != "") {
filterReportData = filterReportData.filter(item => {
return (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" && item.approvalYear <= yearFilter.end + "년" : null;
});
}
if (gubun !== "") { // 구분검색
filterReportData = filterReportData.filter(item => (item.plantZoneGugun) ? String(item.plantZoneGugun).includes(String(gubun)) : null);
}
console.log('report count:', filterReportData.length);
setTableCount(filterReportData.length || 0);
filterReportData = filterReportData.slice((curPage - 1) * 10, curPage * 10); // paging
filterReportData = filterReportData?.map((item, index) => ({ ...item, no: (curPage - 1) * 10 + index + 1 }));
//const fileList = await getDcFile("CLS20250530000041");
addFileName(filterReportData).then(data => {
filterReportData = data;
setTableData(filterReportData || []);
});
setTableData(filterReportData || []);
}
setShowTable(true);
@@ -343,17 +386,13 @@ const SearchModal: React.FC<SearchModalProps> = ({
cqlFilters.push(`fclt_cpct BETWEEN ${start1} AND ${end1}`);
else if (start1) cqlFilters.push(`fclt_cpct >= ${start1}`);
else if (end1) cqlFilters.push(`fclt_cpct <= ${end1}`);
// 시도
if (ctpvName) cqlFilters.push(`ctpv_nm ILIKE '%${ctpvName}%'`);
if (sggName) cqlFilters.push(`sgg_nm ILIKE '%${sggName}%'`);
// // 처리구역 면적
// if (start2 && end2)
// cqlFilters.push(`prcsZoneAreaSum BETWEEN ${start2} AND ${end2}`);
// else if (start2) cqlFilters.push(`prcsZoneAreaSum >= ${start2}`);
// else if (end2) cqlFilters.push(`prcsZoneAreaSum <= ${end2}`);
// // 하수처리시설명
// if (var1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${var1}%'`);
// 처리구역 면적
if (start2 && end2)
cqlFilters.push(`prcsZoneAreaSum BETWEEN ${start2} AND ${end2}`);
else if (start2) cqlFilters.push(`prcsZoneAreaSum >= ${start2}`);
else if (end2) cqlFilters.push(`prcsZoneAreaSum <= ${end2}`);
// 하수처리시설명
if (var1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${var1}%'`);
return cqlFilters;
};
// 하수처리구역용 CQL 필터 생성
@@ -449,7 +488,12 @@ const SearchModal: React.FC<SearchModalProps> = ({
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
const handleSearch = () => {
setCurPage(1); // 페이지를 1로 초기화
setCurPage(1); // 페이지를 1로 초기화
// setDetailCurPage(1); // 페이지를 1로 초기화
// setIsResetPage(false); // 페이지를 초기화
// setIsResetDetailPage(true); // 디테일 페이지를 초기화
// setIsResetSelection(true); // 선택 초기화
// setIsResetDetailSelection(true); // 선택 초기화
fetchFilteredData();
setIsResetPage(true); // 페이지를 초기화
setIsResetDetailPage(true); // 디테일 페이지를 초기화
@@ -482,11 +526,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
bizId: tableData[index % 5].bizId,
};
RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"'));
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
console.log('운영정보 cellClick 데이터:', res);
console.log('운영정보 cellClick.data:', res.data);
console.log('운영정보 length:', res.data.length);
const mappedData = (res.data || []).map((item: any, detailIndex: number) => {
@@ -496,14 +537,12 @@ const SearchModal: React.FC<SearchModalProps> = ({
const mqltCdObj = MS_SWAGE_PPL_CODES.find(code => code.val === item.mqltCd.trim());
return {
...formattedItem,
rowNumber: (detailCurPage - 1) * 5 + detailIndex + 1,
rowNumber: (detailCurPage - 1) * 4 + detailIndex + 1,
usgCd: usgCdObj ? usgCdObj.text : item.usgCd,
mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd,
};
});
console.log('운영정보 cellClick mappedData:', mappedData);
setDetailTableData(mappedData);
setDetailTableCount(res.count || 0);
} catch (error) {
@@ -534,7 +573,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const mqltCdObj = MS_SWAGE_PPL_CODES.find(code => code.val === item.mqltCd.trim());
return {
...formattedItem,
rowNumber: (detailCurPage - 1) * 5 + detailIndex + 1,
rowNumber: (detailCurPage - 1) * 4 + detailIndex + 1,
usgCd: usgCdObj ? usgCdObj.text : item.usgCd,
mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd,
};
@@ -549,7 +588,31 @@ const SearchModal: React.FC<SearchModalProps> = ({
}
}
};
// 하수도정비기본계획 테이블 cellClick 핸들러
const handleReportCellClick = (index: number | undefined, headId?: String) => {
console.log(index);
if (typeof index === "number" && tableData[index]) {
const reportData = tableData[index];
const fileName = reportData.fileName;
const filePath = reportData.filePath;
if (reportData.fileSn !== "") {
getFileDownload(reportData.fileSn, fileName, filePath);
}
}
};
const handleCtpvCdChange = (val: string | number) => { // 하수도정비기본계획.시도
const sidoOption = sidos.find((n) => n.val === val);
setCtpvCd(String(val));
if (val !== '0') {
const filterSiguns = siguns.filter(item => item.sido === sidoOption?.text);
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ start: "", end: "", });
}
const renderBody = () => (
<>
@@ -563,64 +626,74 @@ const SearchModal: React.FC<SearchModalProps> = ({
onValueChange={(value: string) => setActiveTab(value)}
>
</UITab>
{/* 각각의 탭 영역 */}
{/* 기본정보 탭 */}
{activeTab === 'basic' && (
<BasicTab
open={open}
basicType={basicType}
city={city}
sgg={sgg}
start1={start1}
start2={start2}
end1={end1}
end2={end2}
var1={var1}
var2={var2}
yearFilter={yearFilter}
handleSearch={handleSearch}
setBasicType={setBasicType}
setCity={setCity}
setCtpvName={setCtpvName}
setSgg={setSgg}
setSggName={setSggName}
setYearFilter={setYearFilter}
setStart1={setStart1}
setStart2={setStart2}
setEnd1={setEnd1}
setEnd2={setEnd2}
setVar1={setVar1}
setVar2={setVar2}
/>
)}
{/* 운영정보 탭 */}
{activeTab === 'operation' && (
<OperationTab
open={open}
workType={workType}
var1={var1}
var2={var2}
yearFilter={yearFilter}
handleSearch={handleSearch}
setWorkType={setWorkType}
setVar1={setVar1}
setVar2={setVar2}
setYearFilter={setYearFilter}
/>
)}
{/* 하수도정비기본계획보고서 탭 */}
{activeTab === 'report' && (
<ReportTab
open={open}
/>
)}
{/* </UITab2> */}
{/* 각각의 탭 영역 */}
{/* 기본정보 탭 */}
{activeTab === 'basic' && (
<BasicTab
open={open}
basicType={basicType}
city={city}
sgg={sgg}
start1={start1}
start2={start2}
end1={end1}
end2={end2}
var1={var1}
var2={var2}
yearFilter={yearFilter}
handleSearch={handleSearch}
setBasicType={setBasicType}
setCity={setCity}
setSgg={setSgg}
setYearFilter={setYearFilter}
setStart1={setStart1}
setStart2={setStart2}
setEnd1={setEnd1}
setEnd2={setEnd2}
setVar1={setVar1}
setVar2={setVar2}
/>
)}
{/* 운영정보 탭 */}
{activeTab === 'operation' && (
<OperationTab
open={open}
workType={workType}
var1={var1}
var2={var2}
yearFilter={yearFilter}
handleSearch={handleSearch}
setWorkType={setWorkType}
setVar1={setVar1}
setVar2={setVar2}
setYearFilter={setYearFilter}
/>
)}
{/* 하수도정비기본계획보고서 탭 */}
{activeTab === 'report' && (
<ReportTab
open={open}
gubun={gubun}
sidos={sidos}
ctpvCd={ctpvCd}
sigungu={sigungu}
filteredSiguns={filteredSiguns}
yearFilter={yearFilter}
handleSearch={handleSearch}
handleCtpvCdChange={handleCtpvCdChange}
setYearFilter={setYearFilter}
setGubun={setGubun}
setSigungu={setSigungu}
/>
)}
{/* </UITab2> */}
{/* 📋 결과 리스트 */}
{/* 하수도정비기본계획보고서 탭 */}
{activeTab === 'basic' && (
{/* 기본정보 탭, 하수도정비기본계획보고서 탭 */}
{(activeTab === 'basic' || activeTab === 'report') && (
<div className="h-[79vh] w-full overflow-hidden rounded-lg border">
{/* 테이블2 영역 (가로/세로 스크롤 가능) */}
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isLoading} />
<UiTable
@@ -633,7 +706,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
headlist={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={handleBasicCellClick}
cellClick={activeTab === 'report' ? handleReportCellClick : handleBasicCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
@@ -667,7 +740,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
</div>
<div className="h-[39vh] w-full overflow-hidden rounded-lg border">
{/* 테이블2 영역 */}
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isDetailLoading} />
<UiTable
@@ -31,6 +31,12 @@ const SwageMhl: React.FC<SwageMhlProps> = ({
handleSearch,
}) => {
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSearch();
}
};
return (
<div className="mb-3">
<div className="mb-2 flex items-center">
@@ -49,11 +55,10 @@ const SwageMhl: React.FC<SwageMhlProps> = ({
endLabel=""
/>
{/* 용도 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">용도</Label>
<SelectBox
className="w-60 mr-8"
className="ml-8 w-60 mr-8"
selectClass="rounded-lg bg-white text-xl"
label=""
label="용도"
selectArray={MS_SWAGE_MHL_USE_CODES}
value={var1}
onSelectValue={(val) => {
@@ -62,7 +67,7 @@ const SwageMhl: React.FC<SwageMhlProps> = ({
selectContentClass="z-[101]"
/>
{/* 하수맨홀 구경 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">구경(mm)</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">구경(mm)</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
@@ -72,12 +77,7 @@ const SwageMhl: React.FC<SwageMhlProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setStart1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
@@ -89,12 +89,7 @@ const SwageMhl: React.FC<SwageMhlProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -32,6 +32,12 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
handleSearch,
}) => {
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSearch();
}
};
return (
<div className="mb-3">
<div className="flex items-center mb-2">
@@ -44,7 +50,7 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
endLabel=""
/>
{/* 일일처리용량 - 오수맨홀 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">일일처리용량(㎥)</Label>
<Label className="ml-8 mr-2 w-auto text-xl text-gray-600">일일처리용량(㎥)</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
@@ -54,12 +60,7 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setStart1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
@@ -71,15 +72,12 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
{/* 양수능력 - 우수맨홀 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">양수능력(m²/d)</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">
양수능력(m²/d)
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
@@ -89,12 +87,7 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setStart2(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
@@ -106,12 +99,7 @@ const SwagePmstn: React.FC<SwagePmstnProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd2(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -10,16 +10,12 @@ interface SwagePplProps {
var1: string;
var2: string;
start1: string;
start2: string;
end1: string;
end2: string;
yearFilter: { start: string; end: string };
setVar1: (value: string) => void;
setVar2: (value: string) => void;
setStart1: (value: string) => void;
setStart2: (value: string) => void;
setEnd1: (value: string) => void;
setEnd2: (value: string) => void;
setYearFilter: (filter: { start: string; end: string }) => void;
handleSearch: () => void;
}
@@ -28,20 +24,22 @@ const SwagePpl: React.FC<SwagePplProps> = ({
var1,
var2,
start1,
start2,
end1,
end2,
yearFilter,
setVar1,
setVar2,
setStart1,
setStart2,
setEnd1,
setEnd2,
setYearFilter,
handleSearch,
}) => {
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSearch();
}
};
return (
<div className="mb-6">
<div className="mb-2 flex items-center">
@@ -60,11 +58,10 @@ const SwagePpl: React.FC<SwagePplProps> = ({
endLabel=""
/>
{/* 용도 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">용도</Label>
<SelectBox
className="w-40 mr-8"
className="ml-8 w-60 mr-8"
selectClass="rounded-lg bg-white text-xl"
label=""
label="용도"
selectArray={MS_SWAGE_PPL_USE_CODES}
value={var1}
onSelectValue={(val) => {
@@ -73,11 +70,10 @@ const SwagePpl: React.FC<SwagePplProps> = ({
selectContentClass="z-[101]"
/>
{/* 재질 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">재질</Label>
<SelectBox
className="w-60 mr-8"
selectClass="rounded-lg bg-white text-xl"
label=""
label="재질"
selectArray={MS_SWAGE_PPL_CODES}
value={var2}
onSelectValue={(val) => {
@@ -86,22 +82,17 @@ const SwagePpl: React.FC<SwagePplProps> = ({
selectContentClass="z-[101]"
/>
{/* 관경 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">관경(mm)</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">관경(mm)</Label>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={start1}
value={var1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setStart1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
setVar1(val);
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
@@ -113,47 +104,32 @@ const SwagePpl: React.FC<SwagePplProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
{/* 연장 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">연장(m)</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">연장(m)</Label>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={start2}
value={start1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setStart2(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
setStart1(val);
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={end2}
value={end1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd2(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
setEnd1(val);
}}
onKeyDown={handleEnterKey}
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -1,10 +1,8 @@
// 하수처리시설
import React from 'react';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { Button, Input, Label } from '@common/components';
import { SidoSigunguSelectBox } from '@/components/ui/SidoSigunguSelectBox';
import React from 'react';
interface SwagePrcsFcltProps {
var1: string;
@@ -12,53 +10,42 @@ interface SwagePrcsFcltProps {
start2: string;
end1: string;
end2: string;
city: number;
sgg: number;
yearFilter: { start: string; end: string };
setVar1: (value: string) => void;
setStart1: (value: string) => void;
setStart2: (value: string) => void;
setEnd1: (value: string) => void;
setEnd2: (value: string) => void;
setCity: (value: number) => void;
setCtpvName: (name: string) => void;
setSgg: (value: number) => void;
setSggName: (name: string) => void;
setYearFilter: (filter: { start: string; end: string }) => void;
handleSearch: () => void;
}
const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
var1,
start1,
start2,
end1,
city,
sgg,
end2,
yearFilter,
setVar1,
setStart1,
setStart2,
setEnd1,
setCity,
setCtpvName,
setSgg,
setSggName,
setEnd2,
setYearFilter,
handleSearch,
}) => {
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSearch();
}
};
return (
<div className="mb-3">
{/* 가동개시일자 */}
<div className="mb-2 flex items-center">
<SidoSigunguSelectBox
sido={city}
sigungu={sgg}
onSidoChange={(sidoId) => {
setCity(sidoId);
setSgg(0);
}}
onSigunguChange={setSgg}
setCtpvName={setCtpvName}
setSggName={setSggName}
/>
{/* 가동개시일자 */}
<Label className="mr-2 w-auto text-xl text-gray-600">가동개시일자</Label>
<YearRangeSelectBox
start={yearFilter.start}
@@ -74,7 +61,7 @@ const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
endLabel=""
/>
{/* 시설용량 */}
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시설용량(㎥/d)</Label>
<Label className="ml-8 mr-2 w-auto text-xl text-gray-600">시설용량(㎥/d)</Label>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
@@ -84,12 +71,7 @@ const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setStart1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
@@ -101,12 +83,43 @@ const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd1(val);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
onKeyDown={handleEnterKey}
/>
{/* 처리구역 면적 */}
<Label className="mr-2 w-auto text-xl text-gray-600">처리구역 면적(m²)</Label>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={start2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setStart2(val);
}}
onKeyDown={handleEnterKey}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={end2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd2(val);
}}
onKeyDown={handleEnterKey}
/>
{/* 하수처리시설명 */}
<Label className="mr-2 w-auto text-xl text-gray-600">하수처리시설명</Label>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={var1}
onChange={(e) => {
setVar1(e.target.value);
}}
onKeyDown={handleEnterKey}
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -28,6 +28,12 @@ const swagePrcsZone: React.FC<swagePrcsZoneProps> = ({
handleSearch,
}) => {
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleSearch();
}
};
return (
<div className="mb-3">
<div className="mb-2 flex items-center">
@@ -40,22 +46,7 @@ const swagePrcsZone: React.FC<swagePrcsZoneProps> = ({
}}
onSigunguChange={setSgg}
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리시설명</Label>
<Input
className='!text-xl w-[120px] placeholder:text-center mr-8'
placeholder="입력"
value={var2}
onChange={(e) => {
setVar2(e.target.value);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리구역명</Label>
<Label className="mr-2 w-auto text-xl text-gray-600">하수처리구역명</Label>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
@@ -63,12 +54,17 @@ const swagePrcsZone: React.FC<swagePrcsZoneProps> = ({
onChange={(e) => {
setVar1(e.target.value);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
onKeyDown={handleEnterKey}
/>
<Label className="mr-2 w-auto text-xl text-gray-600">하수처리시설명</Label>
<Input
className='!text-xl w-[120px] placeholder:text-center mr-8'
placeholder="입력"
value={var2}
onChange={(e) => {
setVar2(e.target.value);
}}
onKeyDown={handleEnterKey}
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -218,24 +218,23 @@ const BaseLayout = ({
<div className="flex items-center w-full">
{showDatePicker && ( // showDatePicker 값에 따라 DatePicker 렌더링
<>
<Label className="ml-2 mr-4 w-20 text-xl font-medium text-gray-600 whitespace-nowrap">상수사용기간</Label>
<Label className="mr-4 w-20 text-xl text-gray-600 whitespace-nowrap">상수사용기간</Label>
<DateMonthPicker
field={{
value: aplcnYmFrom || (() => { // aplcnYm이 없으면 현재 연월을 기본값으로 설정
const now = new Date();
const year = now.getFullYear();
// const month = String(now.getMonth() + 1).padStart(2, '0');
// return `${year}${month}`;
return `${year}01`;
const month = String(now.getMonth() + 1).padStart(2, '0');
return `${year}${month}`;
})(), // yyyyMM 형식
onChange: (value: string) => {
setAplcnYmFrom?.(value); // string 값을 직접 전달
}
}}
selectClass="ml-8 w-[100px]"
selectClass="ml-5 w-[100px]"
startYear={1900} // 시작 연도 설정
/>
<span className="font-semibold text-xl mx-4">~</span>
<span className="font-semibold text-xl mx-2">~</span>
<DateMonthPicker
field={{
value: aplcnYmTo || (() => { // aplcnYm이 없으면 현재 연월을 기본값으로 설정
@@ -248,7 +247,7 @@ const BaseLayout = ({
setAplcnYmTo?.(value); // string 값을 직접 전달
}
}}
selectClass="w-[100px] mr-8"
selectClass="w-[100px]"
startYear={1900} // 시작 연도 설정
/>
</>
@@ -259,40 +258,21 @@ const BaseLayout = ({
setRtnEnvPartSidoValue={(val) => setCtpvCd?.(val)}
setRtnEnvPartSigunValue={setSigungu} // 선택된 시군구 값을 받을 콜백 함수 전달
>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-4">하수처리장</Label>
<SelectBox
label={''}
value={selectedSwageTreatmentPlant}
selectArray={treatmentFacilityOptions}
className="w-[160px]"
selectClass="rounded-lg bg-white truncate"
onSelectValue={(val) => onSwageTreatmentPlantChange?.(val)}
selectContentClass="z-[101]"
/>
<SelectBox label={"하수처리장"} value={selectedSwageTreatmentPlant} selectArray={treatmentFacilityOptions} className="col-span-3" selectClass="ml-5 rounded-lg bg-white truncate" onSelectValue={(val) => onSwageTreatmentPlantChange?.(val)} selectContentClass="z-[101]" />
{/* <SelectBox label={"하수처리구역"} value={selectedSwageProcessingZone} selectArray={processingZoneOptions} className="col-span-3" selectClass="rounded-lg bg-white truncate" onSelectValue={(val) => onSwageProcessingZoneChange?.(val)} selectContentClass="z-[101]" /> */}
</GovSidoSigunguSearchForm>
{selectBox?.searchChk && (
<div className='flex flex-1 justify-end mr-6'>
<Button size="sm" onClick={() => selectBox.onSearchClick?.()}>조회</Button>
</div>
)}
{selectBox?.searchChk ? <SearchFormRight><Button size="sm" onClick={() => selectBox.onSearchClick?.()}>조회</Button></SearchFormRight> : null}
</div>
</ListDiv>
<ListDiv>
<div className="card-header">
<h3 className="text-2xl font-medium">{titleName.firstCardTitle}</h3>
<div>
{graphBtn && (
<Button className="px-4 py-2 !mr-[1.2rem] bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700" size="sm" onClick={isChckFile}>파일 다운로드</Button>
)}
{graphBtn ? <Button className="px-4 py-2 !mr-[1.2rem] bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700" size="sm" onClick={isChckFile}>파일 다운로드</Button> : null}
{/* 그래프 있을 시 */}
{graphBtn && (
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm" onClick={isDeleteFile}>삭제</Button>
)}
{graphBtn ? <Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm" onClick={isDeleteFile}>삭제</Button> : null}
{/* 분석 버튼 */}
{analysisBtn && (
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm" onClick={onAnalysis}>{analysisBtn}</Button>
)}
{analysisBtn ? <Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm" onClick={onAnalysis}>{analysisBtn}</Button> : null}
</div>
</div>
<Form {...form}>
@@ -304,23 +284,19 @@ const BaseLayout = ({
</form>
</Form>
</ListDiv>
{children?.[1] != null && (
<ListDiv>
<div className="card-header flex items-center">
{
children?.[1] != null ? <ListDiv>
<div className="card-header flex items-center justify-between">
<h3 className="text-2xl font-medium">{titleName?.secondCardTitle}</h3>
<div className='flex flex-1 justify-end mr-8'>
{graphBtn && (
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm">파일 다운로드</Button>
)}
<div>
{graphBtn ? <Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm">파일 다운로드</Button> : null}
{/* 그래프 있을 시 */}
{graphBtn && (
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm">삭제</Button>
)}
{graphBtn ? <Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm">삭제</Button> : null}
</div>
</div>
<div className="card !m-[1.2rem]">{children?.[1]}</div>
</ListDiv>
)}
</ListDiv> : null
}
</Form>
)
}
@@ -47,7 +47,7 @@ interface ApiSelectOption {
}
const IrSetting = () => {
const [input1, setInput1] = useState('0.8'); // 오수전환율 초기값
const [input1, setInput1] = useState('');
const [input2, setInput2] = useState('');
const [select1, setSelect1] = useState('0'); // 환경청코드
const [select2, setSelect2] = useState('0'); // 시도코드
@@ -387,7 +387,10 @@ const IrSetting = () => {
accept={".xls, .xlsx, .xlsm, .xltx"}
fileIdx={2} />
</FormSection>
<FormSection name='inputdate' form={form} titleNm='▷ 상수사용량 적용월'>
<FormSection
name='inputdate'
form={form}
titleNm='▷ 상수사용량 적용월'>
{/* 연월 선택 라이브러리로 수정 필요 */}
<DateMonthPicker
field={{
@@ -396,11 +399,14 @@ const IrSetting = () => {
setSelectedDate(value);
}
}}
selectClass="ml-5 w-[225px]"
selectClass="ml-5 w-[150px]"
startYear={1900} // 시작 연도 설정
/>
</FormSection>
<FormSection name='rtkSource' form={form} titleNm='▷ 오수전환율'>
<FormSection
name='rtkSource'
form={form}
titleNm='▷ 오수전환율'>
<Input
value={input1}
onChange={(e) => {
@@ -424,23 +430,18 @@ const IrSetting = () => {
setInput1(newValue);
}}
className="ml-5 h-[3.2rem] text-center text-xl w-[225px]"
className="ml-5 h-[3.2rem] text-center text-xl w-[150px]"
placeholder="예: 0.75"
/>
</FormSection>
<FormSection name='analysis information' form={form} titleNm='▷ 분석 정보'>
<FormSection
name='analysis information'
form={form}
titleNm='▷ 분석 정보'>
<Input
value={input2}
onChange={(e) => setInput2(e.target.value)}
className="ml-5 h-[3.2rem] text-center text-xl w-[225px]"
placeholder='세부 분석정보 입력'
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleAnalysisClick();
}
}}
/>
className="ml-5 h-[3.2rem] text-center text-xl w-[150px]" />
</FormSection>
<ListDiv>
<div className="card !m-[1.2rem]">
@@ -61,8 +61,8 @@ const defaultFormValues: FormSchemaType = {
sggCd: "",
swageTmplntCd: "",
swtrmtZoneCd: "",
rtkSource: "",
rdiiArea: "", // 문자열로 기본값 설정
rtkSource: "출처",
rdiiArea: "123", // 문자열로 기본값 설정
unitFactors: [
{ response: "Short-Term", R: "0.040", T: "0.5", K: "1" }, // 문자열로 기본값 설정
{ response: "Medium-Term", R: "0.005", T: "1", K: "2" },
@@ -78,7 +78,7 @@ const defaultFormValues: FormSchemaType = {
aplcnYm: "",
rate: "0.8", // 문자열로 기본값 설정
// rainFile: undefined,
analysisInfo: "",
analysisInfo: "test 분석정보",
date: (() => { // 현재 연월을 yyyyMM 형식으로 설정
const now = new Date();
const year = now.getFullYear();
@@ -501,7 +501,7 @@ export default function RTKForm() {
form.setValue("rate", newValue, { shouldValidate: true }); // form의 rate 필드에 설정
}}
className="h-12 text-center text-xl w-[225px] ml-5"
placeholder="0 ~ 1 사이의 값 입력"
placeholder="예: 0.75"
/>
</FormSection>
<FormSection name='date' form={form} titleNm='○ 상수사용량 적용월'>
@@ -512,24 +512,17 @@ export default function RTKForm() {
form.setValue("date", value, { shouldValidate: true }); // form의 date 필드에 직접 설정
}
}}
selectClass="ml-5 w-[225px]"
selectClass="ml-5 w-[200px]"
startYear={1900} // 시작 연도 설정
/>
</FormSection>
<FormSection name='rate' form={form} titleNm='○ 분석 정보'>
<Input
{...form.register("analysisInfo")}
className="h-12 text-center text-xl w-[225px] ml-5"
placeholder='세부 분석정보 입력'
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleAnalysisClick();
}
}}
/>
<Input {...form.register("analysisInfo")} className="h-12 text-center text-xl w-[225px] ml-5" />
</FormSection>
</div>
{/* <div className="flex justify-end mt-1">
<Button size="sm" type="submit" onClick={handleAnalysisClick}>RDII분석 실행</Button>
</div> */}
</div>
]}
</BaseLayout >
@@ -22,9 +22,8 @@ const formSchema = z.object({
aplcnYmFrom: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경
const now = new Date();
const year = now.getFullYear();
// const month = String(now.getMonth() + 1).padStart(2, '0');
// return `${year}${month}`;
return `${year}01`; // 기본값을 1월로 설정
const month = String(now.getMonth() + 1).padStart(2, '0');
return `${year}${month}`;
}), // 분석기간 시작연월
aplcnYmTo: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경
const now = new Date();
@@ -67,9 +66,8 @@ const Result = () => {
aplcnYmFrom: (() => { // 현재 연월을 yyyyMM 형식으로 설정
const now = new Date();
const year = now.getFullYear();
// const month = String(now.getMonth() + 1).padStart(2, '0');
// return `${year}${month}`;
return `${year}01`;
const month = String(now.getMonth() + 1).padStart(2, '0');
return `${year}${month}`;
})(),
aplcnYmTo: (() => { // 현재 연월을 yyyyMM 형식으로 설정
const now = new Date();
@@ -22,9 +22,8 @@ const formSchema = z.object({
aplcnYmFrom: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경
const now = new Date();
const year = now.getFullYear();
// const month = String(now.getMonth() + 1).padStart(2, '0');
// return `${year}${month}`;
return `${year}01`;
const month = String(now.getMonth() + 1).padStart(2, '0');
return `${year}${month}`;
}), // 분석기간 시작연월
aplcnYmTo: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경
const now = new Date();
@@ -63,9 +62,8 @@ const Result = () => {
aplcnYmFrom: (() => { // 현재 연월을 yyyyMM 형식으로 설정
const now = new Date();
const year = now.getFullYear();
// const month = String(now.getMonth() + 1).padStart(2, '0');
// return `${year}${month}`;
return `${year}01`;
const month = String(now.getMonth() + 1).padStart(2, '0');
return `${year}${month}`;
})(),
aplcnYmTo: (() => { // 현재 연월을 yyyyMM 형식으로 설정
const now = new Date();
@@ -160,12 +160,6 @@ const Page = () => {
className='w-[100px]'
value={usr}
onChange={(e) => setUsr(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
</div>
<div className='flex items-center'>
@@ -174,12 +168,6 @@ const Page = () => {
className='w-[100px]'
value={pjNm}
onChange={(e) => setpjNm(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
</div>
</div>
@@ -114,8 +114,8 @@ const Page = () => {
atflId: id,
dcrpPplMtncBizNm: fileNm
})
if (data) {
alert('파일이 등록되었습니다.');
if (data) {
alert('파일이 등록되었습니다.');
setIsModalOpen(false);
handleSearch();
}
@@ -154,12 +154,6 @@ const Page = () => {
className='w-[100px] !text-2xl'
value={usr}
onChange={(e) => setUsr(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
</div>
<div className='flex items-center'>
@@ -168,12 +162,6 @@ const Page = () => {
className='w-[100px] !text-2xl'
value={pjNm}
onChange={(e) => { setpjNm(e.target.value) }}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
</div>
</div>
+3 -14
View File
@@ -85,8 +85,9 @@ export const deleteData = async (url: string, data?: object): Promise<any> => {
return res;
};
// DC API 호출
// RSONE DC API 호출
export const getDcData = async (url: string, data?: object): Promise<any> => {
console.log(url);
const res = await fetch('/dc-service' + url, {
method: "GET",
});
@@ -97,7 +98,7 @@ export const getDcData = async (url: string, data?: object): Promise<any> => {
throw new Error('Failed to fetch data');
};
// CMS API 호출
// RSONE DC API 호출
export const getCmsData = async (url: string, data?: object): Promise<any> => {
console.log(url);
const res = await fetch('/cms-service' + url, {
@@ -110,18 +111,6 @@ export const getCmsData = async (url: string, data?: object): Promise<any> => {
throw new Error('Failed to fetch data');
};
// GeoServer API 호출
export const getGeoData = async (url: string, data?: object): Promise<any> => {
const res = await fetch('/geoserver' + url, {
method: "GET",
});
if (res.ok) {
const data = await res.json();
return data;
}
throw new Error('Failed to fetch data');
};
export function getCookie(name: string) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match && match[2]) {
+3 -5
View File
@@ -103,10 +103,8 @@ export const formatDateString = (dateStr: string): string => {
}
const year = cleanStr.substring(0, 4);
const month = cleanStr.substring(4, 6); // parseInt로 앞의 0 제거
// const month = parseInt(cleanStr.substring(4, 6)); // parseInt로 앞의 0 제거
// const day = parseInt(cleanStr.substring(6, 8)); // parseInt로 앞의 0 제거
const day = cleanStr.substring(6, 8); // parseInt로 앞의 0 제거
const month = parseInt(cleanStr.substring(4, 6)); // parseInt로 앞의 0 제거
const day = parseInt(cleanStr.substring(6, 8)); // parseInt로 앞의 0 제거
return `${year}-${month}-${day}`;
return `${year}년 ${month}월 ${day}일`;
};
@@ -21,7 +21,7 @@ export const formatDisplayData = (data: { [key: string]: any }): { [key: string]
if (/^\d{6}$/.test(dateStr)) {
const year = dateStr.substring(0, 4);
const month = parseInt(dateStr.substring(4, 6));
formattedData[fieldId] = `${year}-${month}`;
formattedData[fieldId] = `${year}년 ${month}월`;
} else {
formattedData[fieldId] = String(value);
}
@@ -45,10 +45,9 @@ export const formatDisplayData = (data: { [key: string]: any }): { [key: string]
// 🎯 undefined 체크 후 parseInt 적용
if (year && month && day && hour && minute) {
// const formattedMonth = parseInt(month);
// const formattedDay = parseInt(day);
// formattedData[fieldId] = `${year}-${formattedMonth}-${formattedDay} ${hour}:${minute}:${second}`;
formattedData[fieldId] = `${year}-${month}-${day} ${hour}:${minute}:${second}`;
const formattedMonth = parseInt(month);
const formattedDay = parseInt(day);
formattedData[fieldId] = `${year}년 ${formattedMonth}월 ${formattedDay}일 ${hour}시 ${minute}분 ${second}초`;
} else {
formattedData[fieldId] = String(value);
}
@@ -1,7 +1,5 @@
import React, { useState, useMemo, useEffect } from "react";
import React, { useMemo } from "react";
import { SelectBox } from '@common/business_components/ui'
import { Label } from '@common/components';
import useStore from '../../store/useStore';
interface Option {
id: number;
@@ -12,72 +10,150 @@ interface SidoSigunguSelectBoxProps {
sido: number;
sigungu: number;
onSidoChange: (id: number) => void;
setCtpvName?: (name: string) => void;
onSigunguChange: (id: number) => void;
setSggName?: (name: string) => void;
className?: string;
}
const sidoList: { id: number, name: string }[] = [
{ id: 0, name: '전체' },
{ id: 26, name: '부산광역시' },
{ id: 28, name: '인천광역시' },
{ id: 30, name: '대전광역시' },
{ id: 41, name: '경기도' },
{ id: 42, name: '강원도' },
{ id: 44, name: '충청남도' },
{ id: 45, name: '전라북도' },
{ id: 46, name: '전라남도' },
{ id: 47, name: '경상북도' },
{ id: 48, name: '경상남도' },
];
const sigunguMap: Record<number, { id: number; name: string }[]> = {
26: [
{ id: 0, name: '전체' },
// ...부산산광역시의 시군구 추가
],
28: [
{ id: 0, name: '전체' },
// ...인천광역시의 시군구 추가
],
30: [
{ id: 0, name: '전체' },
// ...대전광역시의 시군구 추가
],
41: [
{ id: 0, name: '전체' },
{ id: 41820, name: '가평군' },
{ id: 41550, name: '안성시' },
{ id: 41830, name: '양평군' },
{ id: 41670, name: '여주시' },
{ id: 41500, name: '이천시' },
{ id: 41430, name: '의왕시' },
{ id: 41150, name: '의정부시' },
{ id: 41480, name: '파주시' },
{ id: 41650, name: '포천시' },
// ...경기도의 시군구 추가
],
42: [
{ id: 0, name: '전체' },
{ id: 42170, name: '동해시' },
{ id: 42110, name: '춘천시' },
{ id: 42720, name: '홍천군' },
// ...강원도의 시군구 추가
],
44: [
{ id: 0, name: '전체' },
{ id: 44770, name: '서천군' },
// ...충청남도의 시군구 추가
],
45: [
{ id: 0, name: '전체' },
{ id: 45130, name: '군산시' },
{ id: 45190, name: '남원시' },
{ id: 45730, name: '무주군' },
{ id: 45800, name: '부안군' },
{ id: 45770, name: '순창군' },
{ id: 45140, name: '익산시' },
{ id: 45750, name: '임실군' },
{ id: 45710, name: '완주군' },
{ id: 45110, name: '전주시' },
// ...전라북도의 시군구 추가
],
46: [
{ id: 0, name: '전체' },
{ id: 46810, name: "강진군" },
{ id: 46770, name: "고흥군" },
{ id: 46720, name: "곡성군" },
{ id: 46730, name: "구례군" },
{ id: 46230, name: "광양시" },
{ id: 46170, name: "나주시" },
{ id: 46110, name: "목포시" },
{ id: 46840, name: "무안군" },
{ id: 46150, name: "순천시" },
{ id: 46910, name: "신안군" },
{ id: 46130, name: "여수시" },
{ id: 46890, name: "완도군" },
// ...전라남도의 시군구 추가
],
47: [
{ id: 0, name: '전체' },
{ id: 47130, name: "경주시" },
{ id: 47830, name: "고령군" },
{ id: 47190, name: "구미시" },
{ id: 47720, name: "군위군" },
{ id: 47150, name: "김천시" },
{ id: 47280, name: "문경시" },
{ id: 47920, name: "봉화군" },
{ id: 47250, name: "상주시" },
{ id: 47770, name: "영덕군" },
{ id: 47760, name: "영양군" },
{ id: 47210, name: "영주시" },
{ id: 47900, name: "예천군" },
{ id: 47930, name: "울진군" },
{ id: 47730, name: "의성군" },
{ id: 47750, name: "청송군" },
{ id: 47850, name: "칠곡군" },
{ id: 47110, name: "포항시" },
// ...경상북도의 시군구 추가
],
48: [
{ id: 0, name: '전체' },
{ id: 48310, name: "거제시" },
{ id: 48250, name: "김해시" },
{ id: 48270, name: "밀양시" },
{ id: 48220, name: "통영시" },
// ...경상남도의 시군구 추가
],
// ...나머지 시도별 시군구 추가
};
export function SidoSigunguSelectBox({
sido,
sigungu,
onSidoChange,
setCtpvName,
onSigunguChange,
setSggName,
className = "",
}: SidoSigunguSelectBoxProps) {
const { ctpv, sgg} = useStore();
useEffect(() => {
(async () => {
onSidoChange(0);
onSigunguChange(0);
if (setCtpvName && setSggName) {
setCtpvName("");
setSggName("");
}
})();
}, []);
// 선택된 시도에 따라 시군구 리스트를 가져옴
const sigunguList = useMemo(() => sigunguMap[sido] || [{ id: 0, name: '전체' }], [sido]);
return (
<div className={`flex items-center justify-center ${className} mr-8`}>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시도</Label>
<SelectBox
className="w-60 mr-8"
className="w-[150px] mr-8"
selectClass="rounded-lg bg-white"
label=""
selectArray={
[{ val: 0, text: '전체' },
...ctpv.map(opt => ({ val: opt.id, text: opt.name }))
]
}
label="시도"
selectArray={sidoList.map(opt => ({ val: opt.id, text: opt.name }))}
value={sido}
onSelectValue={val => {
onSidoChange(Number(val));
if (setCtpvName) setCtpvName(ctpv.find(opt => Number(opt.id) === Number(val))?.name || "");
}}
onSelectValue={val => onSidoChange(Number(val))}
selectContentClass="z-[101]"
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시군구</Label>
<SelectBox
className="w-48"
selectClass="w-48 rounded-lg bg-white truncate"
label=""
selectArray={
[{ val: 0, text: '전체' },
...sgg
.filter(opt => String(opt.id).slice(0, 2) === String(sido))
.map(opt => ({ val: opt.id, text: opt.name }))
]
}
label="시군구"
selectArray={sigunguList.map(opt => ({ val: opt.id, text: opt.name }))}
value={sigungu}
onSelectValue={val => {
onSigunguChange(Number(val))
if (setSggName) setSggName(sgg.find(opt => Number(opt.id) === Number(val))?.name || "");
}}
onSelectValue={val => onSigunguChange(Number(val))}
selectContentClass="z-[101]"
/>
</div>
@@ -88,9 +88,9 @@ export function YearRangeSelectBox({
};
return (
<div className={`flex items-center mr-8 ${className}`}>
<div className={`flex items-center ${className}`}>
<SelectBox
className="flex-1"
className="flex-1 mr-3"
selectClass={selectClass}
label={startLabel}
selectArray={getStartYearArray()}
@@ -100,7 +100,7 @@ export function YearRangeSelectBox({
/>
<span className="font-semibold text-xl mx-2">~</span>
<SelectBox
className="flex-1"
className="flex-1 ml-1"
selectClass={selectClass}
label={endLabel}
selectArray={getEndYearArray()}
+1 -1
View File
@@ -103,7 +103,7 @@ const FileUploadForm = ({
}}
customPreview={
showPreview ? (
<div className="file-uploader-preview text-center">
<div className="file-uploader-preview">
{files && files.length > 0
? fileName
: "파일을 선택하세요."}
@@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react';
import { SelectBox } from '@common/business_components/ui/select';
import { Label } from '@radix-ui/react-label';
export type comCodeState = {
code: {
@@ -25,9 +24,9 @@ export type comCodeState = {
};
type SelectDataType = {
text: string;
val: string;
sido?: string; // 시도 코드 (선택 사항)
text: string;
val: string;
sido?: string; // 시도 코드 (선택 사항)
}
type EnvPartSelectDataType = SelectDataType & {
@@ -74,9 +73,9 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
const [allSigunOptions, setAllSigunOptions] = useState<SelectDataType[]>([]);
// 조회된 조건에 맞는 환경청 시도 시군 (SelectBox에 실제 사용될 데이터)
const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }]);
const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }]);
const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0', sido: '0' }]);
const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }]);
const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }]);
const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0', sido: '0' }]);
// 시군구 데이터
const getSggCd = async (): Promise<SelectDataType[]> => {
@@ -94,7 +93,7 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
return sggCd;
} catch (error) {
console.error('시군구 데이터를 가져오는데 실패했습니다:', error);
return [{ val: '0', text: '전체', sido: '0' }];
return [{ val: '0', text: '전체', sido: '0' }];
}
};
@@ -113,7 +112,7 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
return cityCd;
} catch (error) {
console.error('시도 데이터를 가져오는데 실패했습니다:', error);
return [{ val: '0', text: '전체', sido: '0' }];
return [{ val: '0', text: '전체', sido: '0' }];
}
};
@@ -136,7 +135,7 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
return lclgvrnmntCd;
} catch (error) {
console.error('환경청 데이터를 가져오는데 실패했습니다:', error);
return [{ val: '0', text: '전체', adstDliStrCd: '', sido: '0' }];
return [{ val: '0', text: '전체', adstDliStrCd: '', sido: '0' }];
}
};
@@ -189,8 +188,8 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
const relevantSigunSidos = Array.from(
new Set(
allSigunOptions
.filter(sigungu => cityCodesInEnvPart.includes(sigungu.val))
.map(sigungu => sigungu.sido)
.filter(sigungu => cityCodesInEnvPart.includes(sigungu.val))
.map(sigungu => sigungu.sido)
)
);
console.log('relevantSigunTexts:', relevantSigunSidos);
@@ -211,8 +210,8 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
// relevantSidos와 relevantSigunsForSidoDerivation은 초기 빈 배열 상태를 유지합니다.
setFilteredEnvPartSidoData([
{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' },
...relevantSidos.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '', sido: '0' }))
{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' },
...relevantSidos.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '', sido: '0' }))
]);
setFilteredEnvPartSigunDataSelected(relevantSigunsForSidoDerivation);
@@ -247,14 +246,14 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
setEnvPartSigunValue('0'); // 시군구 "전체"로 초기화
// 부모에게도 초기화된 값 전달 (text 포함)
if (setRtnEnvPartSidoValue) {
const sidoDefault = filteredEnvPartSidoData.find(item => item.val === '0') || { val: '0', text: '전체' };
// setRtnEnvPartSidoValue(sidoDefault.val); // 이전 방식: 값만 전달
// TODO: 만약 시도 값도 객체로 전달해야 한다면 아래와 같이 수정
// setRtnEnvPartSidoValue({ val: sidoDefault.val, text: sidoDefault.text });
const sidoDefault = filteredEnvPartSidoData.find(item => item.val === '0') || { val: '0', text: '전체' };
// setRtnEnvPartSidoValue(sidoDefault.val); // 이전 방식: 값만 전달
// TODO: 만약 시도 값도 객체로 전달해야 한다면 아래와 같이 수정
// setRtnEnvPartSidoValue({ val: sidoDefault.val, text: sidoDefault.text });
}
if (setRtnEnvPartSigunValue) {
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
}
break;
case 'envPartSido': // 환경청별 - 시도 선택
@@ -263,8 +262,8 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
initializeCityDataByEnvPartSigun(val);
setEnvPartSigunValue('0'); // 시군구 "전체"로 초기화
if (setRtnEnvPartSigunValue) {
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
}
break;
case 'envPartSigun': // 환경청별 - 시군구 선택
@@ -287,11 +286,11 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
setEnvPartSigunValue('0');
// 필터링된 목록들도 초기 "전체" 또는 전체 목록으로 리셋
setFilteredEnvPartSigunData([{ text: "전체", val: '0', sido: '0' }, ...allSigunOptions]);
setFilteredEnvPartSigunData([{ text: "전체", val: '0', sido: '0' }, ...allSigunOptions]);
setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }, ...allEnvPartOptions]);
setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }, ...allSidoOptions.map(s => ({ ...s, adstDliStrCd: '' }))]);
setFilteredEnvPartSigunData([{ text: "전체", val: '0', sido: '0' }, ...allSigunOptions]);
setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }, ...allEnvPartOptions]);
setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '', sido: '0' }, ...allSidoOptions.map(s => ({ ...s, adstDliStrCd: '' }))]);
setFilteredEnvPartSigunData([{ text: "전체", val: '0', sido: '0' }, ...allSigunOptions]);
setFilteredEnvPartSigunDataSelected(allSigunOptions);
@@ -317,35 +316,11 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
return (
isShowPart ? (
<div className="flex items-center my-4">
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
<>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap ml-2 mr-4">환경청</Label>
<SelectBox
className="w-[160px] mr-8"
label={''}
selectArray={filteredEnvPartData}
onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')}
value={envPartValue}
selectClass={'rounded-lg bg-white truncate'}
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-4">시도</Label>
<SelectBox
className="w-[160px] mr-8"
label={''}
selectArray={filteredEnvPartSidoData}
onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')}
value={envPartSidoValue}
selectClass={'rounded-lg bg-white truncate'}
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-4">시군구</Label>
<SelectBox
className="w-[160px] mr-8"
label={''}
selectArray={filteredEnvPartSigunData}
onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')}
value={envPartSigunValue}
selectClass={'rounded-lg bg-white truncate'}
/>
<SelectBox className="col-span-2" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'rounded-lg bg-white truncate'} />
<SelectBox className="col-span-2" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={envPartSidoValue} selectClass={'rounded-lg bg-white truncate'} />
<SelectBox className="col-span-2" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={envPartSigunValue} selectClass={'rounded-lg bg-white truncate'} />
</>
{children}
</div>
+2 -2
View File
@@ -121,7 +121,7 @@ export function VerticalTable({
{headlist?.map((head) => (
<TableRow key={head.id}>
{/* 컬럼 제목 */}
<TableCell className={`font-bold bg-blue-100 text-xs w-[120px] whitespace-nowrap`}>
<TableCell className="font-bold bg-blue-100 text-xs">
{head.title}
</TableCell>
{/* 데이터 값 또는 입력 필드 */}
@@ -168,7 +168,7 @@ export function VerticalTable({
{headlist2?.map((head) => (
<TableRow key={head.id}>
{/* 컬럼 제목 */}
<TableCell className={`font-bold bg-blue-100 text-xs w-[120px] whitespace-nowrap`}>
<TableCell className="font-bold bg-blue-100 text-xs w-fit whitespace-nowrap">
{head.title}
</TableCell>
{/* 데이터 값 또는 입력 필드 */}
-41
View File
@@ -1,41 +0,0 @@
import { useMemo } from "react";
import { create } from "zustand";
import { getGeoData } from "@/components/lib/api";
import { get } from "http";
interface Option { id: number, name: string }
interface SnStoreState {
ctpv: Option[];
sgg: Option[];
fetchCtpvData: () => Promise<void>;
fetchSggData: () => Promise<void>;
}
const useStore = create<SnStoreState>((set) => ({
// Define your store state and actions here
ctpv: [],
sgg: [],
fetchCtpvData: async () => {
const ctpvData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_ctpv&outputFormat=application%2Fjson');
const ctpvList: Option[] = ctpvData.features
.map((feature: any) => ({
id: feature.properties.mctpv_cd.trim(),
name: feature.properties.mctpv_korn_nm
}))
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko'));
set({ ctpv: ctpvList });
},
fetchSggData: async () => {
const sggData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_sgg&outputFormat=application%2Fjson');
const sggList: Option[] = sggData.features
.map((feature: any) => ({
id: feature.properties.sgg_cd,
name: feature.properties.sgg_korn_nm
}))
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko'));
set({ sgg: sggList });
}
}));
export default useStore;
@@ -1,89 +0,0 @@
import { useWrStore } from "@/app/store";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { tableData } from "@/components/lib/func/commom";
import { Title, UiTable } from "@common/business_components/ui";
import { useEffect, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
isRuseReg: { data: any | undefined };
}
const HasuFacility = ({ seletectedLayerNm, viewMode, onClose, onFeatureSelect, isRuseReg }: Props) => {
const {
code,
pbnst,
pubHasuInit,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes, pbnstHasuResCount } = pbnst;
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
const [hasuPage, setHasuPage] = useState<number>(1);
useEffect(() => {
if (code.sggCd.length && pbnstHasuRes.length > 0) {
setHasuTable(tableData(pbnstHasuRes, { code }));
}
}, [code, pbnstHasuRes]);
useEffect(() => {
if (seletectedLayerNm !== '하수처리시설' || viewMode != 'list') return;
if (!pbnst.isInit) {
pubHasuInit("1", "0");
}
}, [pbnst.isInit, pubHasuInit]);
useEffect(() => {
if (seletectedLayerNm !== '하수처리시설' || viewMode != 'list') return;
pubHasuInit(String(hasuPage), "0");
}, [hasuPage, pubHasuInit]);
const hasuCellClick = (index: number | undefined) => {
if (index !== undefined && pbnstHasuRes !== undefined) {
onFeatureSelect(pbnstHasuRes[index]);
onClose();
}
};
return (viewMode == 'list' ? (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 현황" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={hasuTable || []}
headlist={pubFacHeadList}
pageSize={11}
total={pbnstHasuResCount || 0}
headName={""}
cellClick={hasuCellClick}
onPageChange={setHasuPage}
/>
</div>
) :
(
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(0, 4)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(4)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
)
)
}
export default HasuFacility;
@@ -1,83 +0,0 @@
import { useWrStore } from '@/app/store';
import type { customHtdflBdst } from '@/app/store/ruseFcltMng/fcltReg/htdflReg';
import { tableData } from '@/components/lib/func/commom';
import SttnDetailModal from '@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal';
import { Title, UiTable } from '@common/business_components/ui';
import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeColSpan';
import React, { useEffect, useState } from 'react'
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
htdflDetailModal: { isOpen: boolean; data: customHtdflBdst | undefined };
}
const HtdflFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, htdflDetailModal }: Props) => {
const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
const [htdflPage, setHtdflPage] = useState(1)
// 온배수시설 cellClick 이벤트 (상세정보)
const htdflCellClick = (index: number | undefined) => {
if (index !== undefined && htdflTable !== undefined) {
onFeatureSelect(htdflTable[index]);
onClose();
}
};
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
if (!htdflSttn.isInit) {
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
const data = tableData(htdflSttnRes, { code });
const chData = data
.map((item: any) => ({
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].htdflObj,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
}))
.filter((item: any) => item.htdflObj !== undefined);
setHtdflTable(chData);
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
return (
viewMode == 'detail' ? (
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
) : (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="온배수시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={htdflTable || []}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={htdflSttnResCount || 0}
cellClick={(index: number | undefined) => {
htdflCellClick(index ?? undefined);
}}
onPageChange={setHtdflPage}
>
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
</UiTable>
</div>
)
)
}
export default HtdflFacility
@@ -1,105 +0,0 @@
import { useWrStore } from "@/app/store";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
rainDetailModal: { isOpen: boolean; data: customRainBdst | undefined };
}
const RainFacility = ({seletectedLayerNm,viewMode,onFeatureSelect,onClose,rainDetailModal}:Props) => {
// 빗물재이용시설 변수
const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
(state) => state
);
const { rainSttnRes, rainSttnResCount } = rainSttn;
const [rainTable, setRainTable] = useState<customRainBdst[]>();
const [rainPage, setRainPage] = useState(1)
// 빗물재이용시설 cellClick 이벤트 (상세정보)
const rainCellClick = (index: number | undefined, headId: string) => {
if (
index !== undefined &&
rainTable !== undefined &&
headId !== 'chBuildingYn') {
onFeatureSelect(rainTable[index]);
onClose();
}
}
useEffect(() => {
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
console.log('빗물이용시설 초기값 호출', viewMode)
if (!rainSttn.isInit) {
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
useEffect(() => {
const data = tableData(rainSttnRes, { code });
const chData = data
.map((item: any) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst: item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setRainTable(chData);
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
useEffect(() => {
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
return (viewMode == 'detail' ?
(<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />)
: (
<>
<div className="flex justify-between items-center">
<Title title="빗물이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rainTable || []}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={rainSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId);
}}
onPageChange={setRainPage}
>
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
</UiTable>
</>
))
}
export default RainFacility;
@@ -1,146 +0,0 @@
import { useWrStore } from "@/app/store";
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
import { Title, UITab, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useState, useEffect, useCallback } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
setFcltPk: (pk: string) => void;
onFeatureSelect: (feature: any) => void;
onClose: () => void;
actTabData: { id: string; name: string; data: any } | undefined;
tabData: { id: string; name: string; data: any }[];
}
const ResueFacility = ({ viewMode, seletectedLayerNm, tabData, actTabData, setFcltPk, onFeatureSelect, onClose}: Props) => {
const [activeTab, setActiveTab] = useState<string>(''); // 현재 활성화된 탭
// 하수재이용시설 변수
const {
pbnstSttn,
pbnstSttnSearch,
pbnSttnInit,
getFlcts
} = useWrStore((state) => state);
const { fclts, pbnstSttnResCount } = pbnstSttn
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
// 재이용시설 cellClick 이벤트 (상세정보)
const pbnstCellClick = (index: number | undefined) => {
if (
index !== undefined &&
pbnstSttn.pbnstSttnRes &&
pbnstSttn.pbnstSttnRes[index]
) {
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
onClose()
}
};
// 재이용 현황 초기값
useEffect(() => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
if (!pbnstSttn.isInit) {
getFlcts()
}
}, [seletectedLayerNm, pbnstSttn.isInit]);
useEffect(() => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
pbnSttnInit("1", "20", {
partValue: "A",
sidoValue: '0',
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: ""
}, String(new Date().getFullYear()), pbnstSttn.fclts);
}, [fclts, pbnSttnInit, pbnstSttn.fclts, seletectedLayerNm])
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
// 재이용시설 조회
// 재이용시설 페이징처리 관련 함수
const onPageChangeHandler = useCallback((page: number) => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
pbnstSttnSearch(
false,
String(page),
String(20),
{
partValue: "A",
sidoValue: "0",
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: "",
},
"",
String(new Date().getFullYear()), fclts
);
}, [fclts, pbnstSttnSearch]);
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
// const excelClick = useCallback(() => {
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
// excelDownload(
// [[]],
// "하수재이용시설 현황",
// "sample_pbnstSttn.xlsx",
// "A1:U2"
// );
// }, [pbnstSttnSearch]);
return (
viewMode == 'detail' ?
// 재이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수재이용시설 상세정보" />
</div>
<div className="flex justify-between items-center mb-8">
<UITab
defaultValue={activeTab}
tabList={tabData.map((tab) => ({
value: tab.id,
label: tab.name,
onClick: () => setActiveTab(tab.id),
}))}
/>
</div>
<PbnstSttnModal
data={actTabData?.data[0] || ({} as customPbnst)}
titleVisible={false}
/>
</> :
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="하수재이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={pbnstSttnResCount || 0}
cellClick={(index: number | undefined) => {
pbnstCellClick(index);
}}
onPageChange={onPageChangeHandler}
>
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
</UiTable>
</div>
)
}
export default ResueFacility;
@@ -1,103 +0,0 @@
import { useWrStore } from '@/app/store';
import { tableData, formatPhoneNumber } from '@/components/lib/func/commom';
import { Title, UiTable } from '@common/business_components/ui';
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import moment from 'moment';
import React, { useEffect, useState } from 'react'
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
isDmdModal: { data: any | undefined };
}
const ReuseMngFacility = ({seletectedLayerNm, viewMode, onFeatureSelect, onClose, isDmdModal}:Props) => {
const { code,
coSttn,
coSttnInit,
coSttnSearch,
} = useWrStore((state) => state);
const [mngTable, setMngTable] = useState<DemandCompType[]>();
const [mngPage, setMngPage] = useState(1);
const { coSttnRes, coSttnResCount, coSttHeadList } = coSttn;
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode != 'list') return;
if (!coSttn.isInit) {
coSttnInit("1", "20", "0");
}
}, [coSttn.isInit, coSttnInit]);
const coMngCellClick = (index: number | undefined) => {
if (index !== undefined && mngTable !== undefined) {
onFeatureSelect(mngTable[index]);
onClose();
}
};
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
if (coSttnRes) {
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnRes, { code });
const chData = data.map((item: any) => ({
...item,
telno: formatPhoneNumber(item.telno || undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD"),
dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}`
}));
// .filter((item: any) => item !== undefined);
setMngTable(chData);
}
}
}, [coSttnRes, code]);
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
coSttnSearch(String(mngPage), "20", String(0));
}, [coSttnSearch, mngPage]);
return (
viewMode == 'detail'
? (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="수요처 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(0, 3)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(3)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
) : (<div>
<div className="flex justify-between items-center">
<Title title="수요처 현황" />
</div>
<UiTable
headName={[]}
tableData={mngTable || []}
headlist={coSttHeadList}
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
coMngCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
setMngPage(page);
}}
></UiTable></div>)
)
}
export default ReuseMngFacility
@@ -1,107 +0,0 @@
import { useWrStore } from "@/app/store";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { tableData } from "@/components/lib/func/commom";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
rswtrDetailModal: { isOpen: boolean; data: customRswtBdst | undefined };
}
const RswtFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, rswtrDetailModal }: Props) => {
const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
(state) => state
);
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>()
const [rswtrPage, setRswtrPage] = useState(1);
// 중수도시설 cellClick 이벤트 (상세정보)
const rswtCellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
// setViewMode('detail')
onFeatureSelect(rswtrTable[index]);
onClose();
}
}
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
if (!rswtSttn.isInit) {
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
const data = tableData(rswtSttnRes, { code });
const chData = data
.map((item: customRswtBdst) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0]?.rswtrObj,
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
}
})
.filter(
(item: customRswtBdst) =>
item.reuseBuilding[0]?.rswtrObj !== undefined
);
setRswtrTable(chData);
}, [code, rswtSttnRes]);
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
// const rswtSttnExcelDownload = useCallback(() => {
// if (rswtSttn.excelList.length > 0) {
// if (rswtSttn.excelList.length === 0) return;
// excelDownload(
// rswtSttn.excelList,
// "중수도시설 현황",
// "sample_rswtSttn.xlsx",
// "A1:W3",
// );
// }
// }, [rswtSttn.excelList])
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
return (
viewMode == 'detail' ?
// 중수도시설 상세
(
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
) : (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="중수도시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={rswtSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={setRswtrPage}
>
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
</UiTable>
</div>
))
}
export default RswtFacility;
@@ -1,183 +0,0 @@
"use client"
import NewWindowPortal from '@/app/map/components/newWindowPortal';
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { useGisContext } from "@common/business_components/ui/map/Gis";
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ResueFacility from './layerPopup/reuseFacility';
import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from '../util';
import HasuFacility from './layerPopup/hasuFacility';
import RainFacility from './layerPopup/rainFacility';
import RswtFacility from './layerPopup/rswtFacility';
import HtdflFacility from './layerPopup/htdflFacility';
import ReuseMngFacility from './layerPopup/reuseMngFacility';
interface NewWindowPopupProps {
featureData: any;
seletectedLayerNm?: string
onFeatureSelect: (data: any) => void;
onClose: () => void;
}
const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
featureData,
seletectedLayerNm,
onFeatureSelect,
onClose
}) => {
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]);
const [activeTab, setActiveTab] = useState<string>('0');
const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list');
const [fcltPk, setFcltPk] = useState<string>('');
// onClose 함수를 useCallback으로 메모이제이션
const memoizedOnClose = useCallback(() => {
onClose();
}, [onClose]);
// 빗물재이용시설 변수
const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false });
const [rainList, setRainList] = useState<customRainBdst[]>([]);
// 중수도시설 변수
const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false });
const [rswtrList, setRswtrList] = useState<customRswtBdst[]>([]);
// 온배수시설 변수
const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false });
const [htdflList, setHtdflList] = useState<customHtdflBdst[]>([]);
// 하수처리시설 변수
const [hasuList, setHasuList] = useState<pubHasuType[]>([]);
const [isRuseReg, setIsRuseReg] = useState<{
data: any | undefined;
}>({ data: undefined });
// 수요처관리 변수
const [isDmdModal, setIsDmdModal] = useState<{
isMoal: boolean;
data: any | undefined;
}>({ isMoal: false, data: undefined });
const [mngList, setMngList] = useState<DemandCompType[]>([]);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
const getSelectedLayers = () => {
console.trace('호출확인', 1)
let result = null;
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
layers.forEach((layer: any) => {
const source = layer.getSource();
if (source && source.hasFeature && featureData
&& typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
featureLayer = layer; // 피처가 속한 레이어 찾기)
}
});
result = featureLayer.get('lyrNm');
return result;
};
// 상세 목록 데이터 상태 처리
useEffect(() => {
if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] });
}, [hasuList])
useEffect(() => {
if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] });
}, [rainList])
useEffect(() => {
if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] });
}, [rswtrList])
useEffect(() => {
if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
}, [htdflList])
useEffect(() => {
if (mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
}, [mngList])
const lastCalledIdRef = useRef<string | null>(null);
const [layerId, setLayerId] = useState<string | null>();
useEffect(() => {
const layers = getSelectedLayers();
setLayerId(layers);
}, []); // 최초 렌더링 시 호출
// 피쳐 데이터가 변경될 때마다 호출
useEffect(() => {
if (!featureData || typeof featureData.getProperties !== "function" || featureData.getProperties() == '') return;
const selectedProps = featureData.getProperties();
const currentId = featureData.getId?.() || selectedProps?.id || selectedProps?.fid;
// 유효하지 않은 ID는 아예 무시
if (!currentId || typeof currentId !== 'string') return;
// 이전과 동일하면 무시
if (!currentId || currentId === lastCalledIdRef.current) return;
lastCalledIdRef.current = currentId // 새로운 피처일 때만 API 호출
const layerId = getSelectedLayers?.();
if (!layerId || typeof layerId !== 'string') return;
const featureCd =
layerId === '하수재이용시설' ? selectedProps?.swtrmt_fclt_cd :
['빗물이용시설', '중수도시설', '온배수시설', '수요처'].includes(layerId) ? selectedProps?.bdst_nm :
layerId === '하수처리시설' ? selectedProps?.swtrmt_fclt_nm :
null;
if (!featureCd || featureCd === fcltPk) return;
if (layerId === '하수재이용시설') {
fetchpbnstDetail(featureCd, setTabData);
} else if (layerId === '하수처리시설') {
fetchHasuDetail(featureCd, selectedProps?.swtrmt_fclt_cd).then((data) => { setHasuList(data) })
} else {
detainSttn(featureCd, layerId).then((res) => {
if (layerId === '빗물이용시설') setRainList(res);
else if (layerId === '중수도시설') setRswtrList(res);
else if (layerId === '온배수시설') { setHtdflList(res); setHtdflDetailModal({ isOpen: true, data: res[0] }); }
else if (layerId === '수요처') setMngList(res);
});
}
setFcltPk(featureCd);
setActiveTab(featureCd);
setViewMode("detail");
}, [featureData]);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
// 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
const renderConditionalContent = () => {
const actTabData = tabData.find((tab) => tab.id === activeTab);
if (layerId === null || layerId === undefined) {
setLayerId(seletectedLayerNm || '');
}
switch (layerId) {
case '하수재이용시설':
return (<ResueFacility viewMode={viewMode} seletectedLayerNm={layerId} tabData={tabData} actTabData={actTabData} setFcltPk={setFcltPk} onFeatureSelect={onFeatureSelect} onClose={onClose} />)
case '하수처리시설':
return (<HasuFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isRuseReg={isRuseReg} />)
case '빗물이용시설':
return (<RainFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rainDetailModal={rainDetailModal} />)
case '중수도시설':
return (<RswtFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rswtrDetailModal={rswtrDetailModal} />)
case '온배수시설':
return (<HtdflFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} htdflDetailModal={htdflDetailModal} />)
case '수요처':
return(<ReuseMngFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isDmdModal={isDmdModal} />)
default:
break;
}
return null; // 조건에 맞는 콘텐츠가 없을 경우
};
return (
viewMode == 'nothing' ? <></> :
<NewWindowPortal
onClose={memoizedOnClose}
title="시설 상세 정보"
scrollbars='yes'
viewMode={viewMode}
resizable='no'>
{/* 체크된 레이어에 따른 조건부 렌더링 */}
{renderConditionalContent()}
</NewWindowPortal>
);
};
export default NewWindowPopup;
+29 -26
View File
@@ -3,7 +3,7 @@
import Gis from "@common/business_components/ui/map/Gis";
import { useEffect, useRef, useState, useCallback } from "react";
import { mapService } from "../service";
import NewWindowPopup from "../components/newWindowPopup";
import NewWindowPopup from "../newWindowPopup";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
const Map = () => {
@@ -11,7 +11,7 @@ const Map = () => {
const gisMaps = useRef<any | null>(null);
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
const [featureData, setFeatureData] = useState<any>(null); // 선택된 피쳐 데이터
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
@@ -63,25 +63,25 @@ const Map = () => {
let foundFeature: any = null;
let featureId = data.fid;
const layerName = data.layerNm;
console.log("선택된 레이어 이름:", data, layerName);
if (layerName === "하수재이용시설") {
if (layerName === "tb_wr_bdst_ruse_fclt") {
// 재이용시설
featureId = `${layerName}.${data.searchPk}`;
} else if ( //빗물이용시설, 중수도시설
layerName === "빗물이용시설" ||
layerName == "중수도시설"
layerName === "tb_wr_rnwtr_utztn_fclt" ||
layerName == "tb_wr_rswtr_fclt"
) {
featureId = `${layerName}.${data.bdstInfoSn}`;
} else if (layerName === "하수처리시설") { //하수처리시설
} else if (layerName === "tb_il_swage_prcs_fclt") { //하수처리시설
featureId = `${layerName}.${data.bscFctCd}`;
} else if (layerName === "온배수시설") { //온배수시설
} else if (layerName === "tb_wr_htdfl_fclt") { //온배수시설
featureId = `${layerName}.${data.bdstRuseFcltSn}`;
} else if (layerName == "수요처") { //수요처
} else if (layerName == "tb_wr_ruse_fclt_dmd_co") { //수요처
featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`;
} else {
console.warn("해당 레이어에 대한 featureId 매핑 없음", layerName);
featureId = `${layerName}.${data.fid || data.id || data.ftrIdn}`;
}
map
.getLayers()
.getArray()
@@ -111,9 +111,7 @@ const Map = () => {
} else {
console.warn("OpenLayers Feature를 찾을 수 없습니다:", data);
}
const currentId = data?.fid || data?.id || data?.ftrIdn;
const lastId = featureData?.fid || featureData?.id || featureData?.ftrIdn;
if (featureData && currentId === lastId) return; // 이전과 같으면 무시
setFeatureData(data);
setIsOpen(true);
setIsSearchModalOpen(false);
@@ -129,18 +127,7 @@ const Map = () => {
// />
// );
// };
const renderDetailView = useCallback(
(props: any) => (
<NewWindowPopup
key={featureData?.fid || featureData?.id || featureData?.ftrIdn}
onClose={handlePopupClose}
checkedLayers={checkedLayers}
checkedLayersData={checkedLayersData}
{...props}
/>
),
[checkedLayers, checkedLayersData] // 필요 시 의존성 넣기
);
return (
<div className="bg-container">
<Gis
@@ -149,7 +136,24 @@ const Map = () => {
gisMaps={gisMaps}
isMiniMap={false}
searchView={undefined}
detailView={renderDetailView}
// searchView={(props: any) => (
// <MapSearchBar
// searchType="공급처 후보지 조회"
// showApplyButton={false}
// checkedLayers={checkedLayers}
// checkedLayersData={checkedLayersData}
// {...props}
// />
// )
// }
detailView={(props: any) => (
<NewWindowPopup
onClose={handlePopupClose} // 메모이제이션된 함수 사용
checkedLayers={checkedLayers}
checkedLayersData={checkedLayersData}
{...props}
/>
)}
onFeatureSelect={onFeatureSelect}
setIsOpen={setIsOpen}
setFeatureData={setFeatureData}
@@ -159,7 +163,6 @@ const Map = () => {
isSearchModalOpen={isSearchModalOpen}
onCheckedLayersChange={handleCheckedLayersChange}
imgVisble={true}
searchBar={undefined}
/>
</div>
);
+795
View File
@@ -0,0 +1,795 @@
"use client"
import NewWindowPortal from '@/app/map/newWindowPortal';
import { useWrStore } from "@/app/store";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import { formatPhoneNumber, tableData } from "@/components/lib/func/commom";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UITab, UiTable } from '@common/business_components';
import { useGisContext } from "@common/business_components/ui/map/Gis";
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import moment from 'moment';
import React, { useCallback, useEffect, useState } from 'react';
interface NewWindowPopupProps {
featureData: any;
seletectedLayerNm?: string
viewMode?: 'list' | 'detail' | 'nothing'
onFeatureSelect: (data: any) => void;
onClose: () => void;
}
const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
featureData,
seletectedLayerNm,
onFeatureSelect,
onClose
}) => {
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]);
const [activeTab, setActiveTab] = useState<string>('0');
const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list');
const [fcltPk, setFcltPk] = useState<string>('');
// onClose 함수를 useCallback으로 메모이제이션
const memoizedOnClose = useCallback(() => {
onClose();
}, [onClose]);
// 하수재이용시설 변수
const {
code,
pbnstSttn,
pbnstSttnSearch,
pbnSttnInit,
getFlcts
} = useWrStore((state) => state);
const { fclts, pbnstSttnResCount } = pbnstSttn
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
// 빗물재이용시설 변수
const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
(state) => state
);
const { rainSttnRes, rainSttnResCount } = rainSttn;
const [rainTable, setRainTable] = useState<customRainBdst[]>();
const [rainPage, setRainPage] = useState(1)
const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false });
const [rainList, setRainList] = useState<customRainBdst[]>(rainSttnRes || []);
// 중수도시설 변수
const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
(state) => state
);
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>();
const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false });
const [rswtrPage, setRswtrPage] = useState(1);
const [rswtrList, setRswtrList] = useState<customRswtBdst[]>(rswtSttnRes || []);
// 온배수시설 변수
const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false });
const [htdflPage, setHtdflPage] = useState(1)
const [htdflList, setHtdflList] = useState<customHtdflBdst[]>(htdflSttnRes || []);
//하수처리시설 변수
const {
pbnst,
pubHasuInit,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes } = pbnst;
const [hasuList, setHasuList] = useState<pubHasuType[]>(pbnstHasuRes || []);
const [isRuseReg, setIsRuseReg] = useState<{
data: any | undefined;
}>({ data: undefined });
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
const [hasuPage, setHasuPage] = useState<number>(1);
// 수요처관리 변수
const {
coSttn,
coSttnInit,
coSttnSearch,
// getDemandCompList,
// regDemandCompany,
// updateDemandCompany,
// coSttnTxtSearch,
// demandCompList,
} = useWrStore((state) => state);
const [mngTable, setMngTable] = useState<DemandCompType[]>();
const [mngPage, setMngPage] = useState(1);
const { coSttnRes, coSttnResCount, coSttHeadList } = coSttn;
const [isDmdModal, setIsDmdModal] = useState<{
isMoal: boolean;
data: any | undefined;
}>({ isMoal: false, data: undefined});
const [mngList, setMngList] = useState<DemandCompType[]>(coSttnRes || []);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
const getSelectedLayers = () => {
let result = null;
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
layers.forEach((layer: any) => {
const source = layer.getSource();
if (source && source.hasFeature && featureData
&& typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
featureLayer = layer; // 피처가 속한 레이어 찾기)
}
});
result = featureLayer.get('lyrNm');
return result;
};
const fetchpbnstDetail = async (featureCd: string) => {
try {
const response = await getFetch("wr", `/reuseFc/pubFc/${featureCd}`);
// 중복 데이터 추가 방지
setTabDataFunc(response, featureCd);
} catch (error) {
console.error("Error fetching data:", error);
}
};
const fetchHasuDetail = async (featureCd: string, data: string) => {
try {
const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON)
setHasuList(
rainRes.data.map((item: any) => {
return {
...item,
fctCpc: Number(item.fctCpc) || 0,
ruse: item.ruse === false ? "N" : "Y",
};
})
)
} catch (error) {
console.error("Error fetching data:", error);
}
};
const detainSttn = async (featureCd: string, layerNm: string) => {
if (layerNm == 'tb_wr_rnwtr_utztn_fclt') { //빗물이용시설
const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`)
setRainList(res)
}
else if (layerNm == 'tb_wr_rswtr_fclt') { //중수도 시설
const res = await getFetch(fetchType.WR, `/reuseFc/waterreuseFc/1/20/0/${featureCd}`)
setRswtrList(res)
}
else if(layerNm =='tb_wr_ruse_fclt_dmd_co'){ //수요처
const res = await getFetch(fetchType.WR, `/reuseFc/request/1/20/0/${featureCd}`)
setMngList(res)
}
else {
const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`)
setHtdflList(res)
setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] });
}
}
// 상세 목록 데이터 상태 처리
useEffect(() => {
if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] });
}, [hasuList])
useEffect(() => {
if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] });
}, [rainList])
useEffect(() => {
if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] });
}, [rswtrList])
useEffect(() => {
if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
}, [htdflList])
useEffect(() => {
if(mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
},[mngList])
const layerId = getSelectedLayers();
if (featureData && typeof featureData.getProperties === "function") {
const selectedVal = featureData.getProperties();
let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' || layerId == '수요처' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null;
if (featureCd && featureCd !== fcltPk) {
if (layerId == '하수재이용시설') {
featureCd = selectedVal?.swtrmt_fclt_cd;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
setActiveTab(featureCd)
fetchpbnstDetail(featureCd); // 상세정보
}
else if (layerId == '하수처리시설') {
featureCd = selectedVal?.swtrmt_fclt_nm;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd);
}
else {
featureCd = selectedVal?.bdst_nm;
setFcltPk(featureCd)
if (layerId) {
detainSttn(featureCd, layerId);
}
}
setViewMode("detail")
}
} else if (layerId === null && seletectedLayerNm) { setViewMode("list") }
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
///////////////////////////////////////////// 하수재이용시설 //////////////////////////////////////////////////
// 재이용시설 cellClick 이벤트 (상세정보)
const pbnstCellClick = (index: number | undefined) => {
if (
index !== undefined &&
pbnstSttn.pbnstSttnRes &&
pbnstSttn.pbnstSttnRes[index]
) {
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
onClose()
}
};
// 재이용 현황 초기값
useEffect(() => {
if (!pbnstSttn.isInit) {
getFlcts()
}
}, [seletectedLayerNm, pbnstSttn.isInit, getFlcts]);
useEffect(() => {
pbnSttnInit("1", "15", {
partValue: "A",
sidoValue: '0',
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: ""
}, String(new Date().getFullYear()), pbnstSttn.fclts);
}, [fclts, pbnSttnInit, pbnstSttn.fclts])
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
// 재이용시설 상세정보
const setTabDataFunc = (res: any, pk: string) => {
setTabData((prev) => {
if (prev.some((tab) => tab.id === pk)) {
return prev; // 이미 존재하는 탭이면 추가하지 않음
}
return [...prev, { id: pk, name: `재이용시설 ${prev.length + 1}`, data: res }];
});
}
// 재이용시설 조회
// 재이용시설 페이징처리 관련 함수
const onPageChangeHandler = useCallback((page: number) => {
pbnstSttnSearch(
false,
String(page),
String(13),
{
partValue: "A",
sidoValue: "0",
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: "",
},
"",
String(new Date().getFullYear()), fclts
);
}, [fclts, pbnstSttnSearch]);
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
// const excelClick = useCallback(() => {
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
// excelDownload(
// [[]],
// "하수재이용시설 현황",
// "sample_pbnstSttn.xlsx",
// "A1:U2"
// );
// }, [pbnstSttnSearch]);
///////////////////////////////////////////// 하수재이용시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 빗물 재이용 //////////////////////////////////////////////////
// 빗물재이용시설 cellClick 이벤트 (상세정보)
const rainCellClick = (index: number | undefined, headId: string) => {
if (
index !== undefined &&
rainTable !== undefined &&
headId !== 'chBuildingYn') {
// setRainDetailModal({ isOpen: true, data: rainTable[index] })
// setViewMode('detail')
onFeatureSelect(rainTable[index]);
onClose();
}
}
useEffect(() => {
if (!rainSttn.isInit) {
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
useEffect(() => {
const data = tableData(rainSttnRes, { code });
const chData = data
.map((item: any) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst: item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setRainTable(chData);
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
useEffect(() => {
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
///////////////////////////////////////////// 빗물 재이용 //////////////////////////////////////////////////
///////////////////////////////////////////// 중수도 시설 //////////////////////////////////////////////////
// 중수도시설 cellClick 이벤트 (상세정보)
const rswtCellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
// setViewMode('detail')
onFeatureSelect(rswtrTable[index]);
onClose();
}
}
useEffect(() => {
if (!rswtSttn.isInit) {
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
useEffect(() => {
const data = tableData(rswtSttnRes, { code });
const chData = data
.map((item: customRswtBdst) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0]?.rswtrObj,
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
}
})
.filter(
(item: customRswtBdst) =>
item.reuseBuilding[0]?.rswtrObj !== undefined
);
setRswtrTable(chData);
}, [code, rswtSttnRes]);
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
// const rswtSttnExcelDownload = useCallback(() => {
// if (rswtSttn.excelList.length > 0) {
// if (rswtSttn.excelList.length === 0) return;
// excelDownload(
// rswtSttn.excelList,
// "중수도시설 현황",
// "sample_rswtSttn.xlsx",
// "A1:W3",
// );
// }
// }, [rswtSttn.excelList])
useEffect(() => {
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
///////////////////////////////////////////// 중수도 시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 온배수 시설 //////////////////////////////////////////////////
// 온배수시설 cellClick 이벤트 (상세정보)
const htdflCellClick = (index: number | undefined) => {
if (index !== undefined && htdflTable !== undefined) {
onFeatureSelect(htdflTable[index]);
onClose();
}
};
useEffect(() => {
if (!htdflSttn.isInit) {
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
useEffect(() => {
const data = tableData(htdflSttnRes, { code });
const chData = data
.map((item: any) => ({
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].htdflObj,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
}))
.filter((item: any) => item.htdflObj !== undefined);
setHtdflTable(chData);
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
useEffect(() => {
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
///////////////////////////////////////////// 온배수 시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 하수처리 시설 //////////////////////////////////////////////////
useEffect(() => {
if (code.sggCd.length && pbnstHasuRes.length > 0) {
setHasuTable(tableData(pbnstHasuRes, { code }));
}
}, [code, pbnstHasuRes]);
useEffect(() => {
if (!pbnst.isInit) {
pubHasuInit("1", "0");
}
}, [pbnst.isInit, pubHasuInit]);
useEffect(() => {
pubHasuInit(String(hasuPage), "0");
}, [hasuPage, pubHasuInit]);
const hasuCellClick = (index: number | undefined) => {
if (index !== undefined && pbnstHasuRes !== undefined) {
onFeatureSelect(pbnstHasuRes[index]);
onClose();
}
};
///////////////////////////////////////////// 하수처리 시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 수요처 관리 //////////////////////////////////////////////////
useEffect(() => {
if (!coSttn.isInit) {
coSttnInit("1", "13", "0");
}
}, [coSttn.isInit, coSttnInit]);
const coMngCellClick = (index: number | undefined) => {
if (index !== undefined && mngTable !== undefined) {
onFeatureSelect(mngTable[index]);
onClose();
}
};
useEffect(() => {
if (coSttnRes) {
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnRes, { code });
const chData = data.map((item: any) => ({
...item,
telno: formatPhoneNumber(item.telno || undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD"),
dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}`
}));
// .filter((item: any) => item !== undefined);
setMngTable(chData);
}
}
}, [coSttnRes, code]);
useEffect(() => {
coSttnSearch(String(mngPage), "13", String(0));
}, [coSttnSearch, mngPage]);
///////////////////////////////////////////// 수요처 관리 //////////////////////////////////////////////////
// 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
const renderConditionalContent = () => {
const actTabData = tabData.find((tab) => tab.id === activeTab);
let layerId: string | undefined | null = getSelectedLayers();
if (layerId === null || layerId === undefined) {
layerId = seletectedLayerNm || '';
}
//하수처리시설
const isPrcsFclt = layerId == 'tb_il_swage_prcs_fclt'
// 재이용시설
const isPbnst = layerId == 'tb_wr_bdst_ruse_fclt';
// 빗물이용시설
const isRain = layerId == 'tb_wr_rnwtr_utztn_fclt';
// 중수도시설
const isRswt = layerId == 'tb_wr_rswtr_fclt';
// 온배수시설
const isHtdfl = layerId == 'tb_wr_htdfl_fclt';
// 수요처관리
const isReuseMng = layerId == 'tb_wr_ruse_fclt_dmd_co';
if (isPrcsFclt) {
if (viewMode == 'list') {
return (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 현황" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={hasuTable || []}
headlist={pubFacHeadList}
pageSize={10}
total={5000}
headName={""}
cellClick={hasuCellClick}
onPageChange={setHasuPage}
/>
</div>
)
} else {
return (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(0, 4)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(4)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
)
}
}
if (isPbnst) {
if (viewMode == 'detail') {
// 재이용시설 상세
return (
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수재이용시설 상세정보" />
</div>
<div className="flex justify-between items-center mb-8">
<UITab
defaultValue={activeTab}
tabList={tabData.map((tab) => ({
value: tab.id,
label: tab.name,
onClick: () => setActiveTab(tab.id),
}))}
/>
</div>
<PbnstSttnModal
data={actTabData?.data[0] || ({} as customPbnst)}
titleVisible={false}
/>
</>
);
} else {
// 재이용시설 목록
return (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="하수재이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={pbnstSttnResCount || 0}
cellClick={(index: number | undefined) => {
pbnstCellClick(index);
}}
onPageChange={onPageChangeHandler}
>
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
</UiTable>
</div>
);
}
}
if (isRain) {
if (viewMode == 'detail') {
// 빗물이용시설 상세
return (
<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />
);
} else {
// 빗물이용시설 목록
return (
<>
<div className="flex justify-between items-center">
<Title title="빗물이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rainTable || []}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={rainSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId);
}}
onPageChange={setRainPage}
>
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
</UiTable>
</>
);
}
}
if (isRswt) {
if (viewMode == 'detail') {
// 중수도시설 상세
return (
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
);
} else {
// 중수도시설 목록
return (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="중수도시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={rswtSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={setRswtrPage}
>
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
</UiTable>
</div>
);
}
}
if (isHtdfl) {
if (viewMode == 'detail') {
// 온배수시설 상세
return (
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
);
} else {
// 온배수시설 목록
return (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="온배수시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={htdflTable || []}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={htdflSttnResCount || 0}
cellClick={(index: number | undefined) => {
htdflCellClick(index ?? undefined);
}}
onPageChange={setHtdflPage}
>
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
</UiTable>
</div>
);
}
}
if (isReuseMng) {
if (viewMode == 'detail') {
return (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="수요처 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(0, 3)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(3)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
)
} else if(viewMode == 'list') {
return ( <div>
<div className="flex justify-between items-center">
<Title title="수요처 현황" />
</div>
<UiTable
headName={[]}
tableData={mngTable || []}
headlist={coSttHeadList}
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
coMngCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
setMngPage(page);
}}
></UiTable></div>)
}
}
return null; // 조건에 맞는 콘텐츠가 없을 경우
};
return (
viewMode == 'nothing' ? <></> :
<NewWindowPortal
onClose={memoizedOnClose}
title="시설 상세 정보"
width={viewMode == 'list' ? window.screen.availWidth : 1100}
height={viewMode == 'list' ? window.screen.availHeight : layerId == '하수처리시설' && viewMode == 'detail' ? 450 : 900}
scrollbars='yes'
resizable='no'>
{/* 체크된 레이어에 따른 조건부 렌더링 */}
{renderConditionalContent()}
</NewWindowPortal>
);
};
export default NewWindowPopup;

Some files were not shown because too many files have changed in this diff Show More