diff --git a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx index 8d431cf75..b94fc21c1 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx @@ -40,6 +40,14 @@ export const generateYearDates = (searchYear: string) => { return dates; } +type FacilityType = { + bscFctCd: string; + bscFctNm: string; + fcltyCpc: number | ''; + trtFrfNm: string | ''; + efflWqltStndrdNm: string | ''; +} + export default function DashBoard() { // 입력값 상태 관리 const { Common, initializeCommonData, searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); @@ -48,26 +56,10 @@ export default function DashBoard() { const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); const [sidoValue, setSidoValue] = useState('0'); const [sigunValue, setSigunValue] = useState('0'); - const { - isInit, - selectSearchYear, - btnClass, - selectSidoData, - selectSigunData, - } = Common; - - const { - planFcltyList - } = PlanFclty; - - const { - operationalStatusList - } = OperationStatus; - - const { - excelList - } = RainManage; - + const { isInit, selectSearchYear, btnClass, selectSidoData, selectSigunData, } = Common; + const { planFcltyList } = PlanFclty; + const { operationalStatusList } = OperationStatus; + const { excelList } = RainManage; const { chart_inflowRain, chart_bodRain, @@ -79,10 +71,10 @@ export default function DashBoard() { } = MainGraph; /******************선택된 데이터******************/ - // 연도 - const [searchYear, setSearchYear] = useState(selectSearchYear[0]?.val || '0'); + + const [searchYear, setSearchYear] = useState(selectSearchYear[0]?.val || '0'); // 연도 // 시설명 - const [fcltyList, setFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ + const [fcltyList, setFcltyList] = useState({ bscFctCd: '11000SW001R', bscFctNm: '난지', fcltyCpc: 860000, @@ -90,7 +82,7 @@ export default function DashBoard() { efflWqltStndrdNm: '500톤 이상(Ⅲ지역)' }); - const [searchFcltyList, setSearchFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ + const [searchFcltyList, setSearchFcltyList] = useState({ bscFctCd: '', bscFctNm: '', fcltyCpc: '', @@ -111,7 +103,7 @@ export default function DashBoard() { } }, [isInit, initializeCommonData]); - const handleFacilityChange = (facility: { bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }) => { + const handleFacilityChange = (facility: FacilityType) => { setFcltyList(facility); }; @@ -255,60 +247,6 @@ export default function DashBoard() { headerRange: 'A1:J1', sheetName: '주요그래프' } - /* { - data: [['날짜', '강수량'],...chart_inflowRain.map((item) => [item.label, roundNumber(item.barVal0, 1)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '강수량' - }, - { - data: [['날짜', '유입하수량'],...chart_inflowRain.map((item) => [item.label, roundNumber(item.lineVal1, 0)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '유입하수량' - }, - { - data: [['날짜', '시설용량'],...chart_inflowRain.map((item) => [item.label, roundNumber(item.lineVal0, 0)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '시설용량' - }, - { - data: [['날짜', '유입BOD'],...chart_bodRain.map((item) => [item.label, roundNumber(item.lineVal0, 1)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '유입BOD' - }, - { - data: [['날짜', '유입T-P'],...chart_inflTp.map((item) => [item.label, roundNumber(item.val, 3)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '유입T-P' - }, - { - data: [['날짜', '총인유입T-P'],...chart_chongInTp.map((item) => [item.label, roundNumber(item.val, 3)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '총인유입T-P' - }, - { - data: [['날짜', '방류T-P'],...chart_efflTp.map((item) => [item.label, roundNumber(item.val, 3)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '방류T-P' - }, - { - data: [['날짜', '유입T-N'],...chart_inflTn.map((item) => [item.label, roundNumber(item.val, 3)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '유입T-N' - }, - { - data: [['날짜', '방류T-N'],...chart_efflTn.map((item) => [item.label, roundNumber(item.val, 3)])], - headerNum: 1, - headerRange: 'A1:B1', - sheetName: '방류T-N' - } */ ]; downloadMultipleExcel('주요그래프', sheetParameter); diff --git a/apps/fo/app/store/common/index.tsx b/apps/fo/app/store/common/index.tsx index e4aebc982..a381eb50d 100644 --- a/apps/fo/app/store/common/index.tsx +++ b/apps/fo/app/store/common/index.tsx @@ -129,14 +129,14 @@ const selectEnvPartSigunData: SelectDataType[] = [ // ]; // 상향 하향 데이터 -const selectUpdownData:SelectDataType[] = [ +const selectUpdownData: SelectDataType[] = [ { text: "전체", val: '0' }, { text: "500미만", val: '400' }, { text: "500이상", val: '500' }, ]; // 운영 상태 데이터 -const selectOperationData:SelectDataType[] = [ +const selectOperationData: SelectDataType[] = [ { text: "전체", val: '0' }, { text: "가동중", val: '1' }, { text: "재가동", val: '2' }, @@ -145,7 +145,7 @@ const selectOperationData:SelectDataType[] = [ ]; // 시설 구분 데이터 -const selectFacilityPartData:SelectDataType[] = [ +const selectFacilityPartData: SelectDataType[] = [ { text: "전체", val: '0' }, { text: "공공하수처리시설", val: 'SW' }, { text: "오수처리장", val: 'SS' }, @@ -158,12 +158,18 @@ const selectFacilityPartData:SelectDataType[] = [ // 년도 데이터 const getYearData = () => { - const year = new Date().getFullYear(); - const year1 = year - 1; - const year2 = year - 2; - const year3 = year - 3; - const year4 = year - 4; - const year5 = year - 5; + const today = new Date(); + const year = today.getFullYear(); + const month = today.getMonth() + 1; + + // 상반기(6월까지)는 2년 전, 하반기는 1년 전부터 시작 + const startYear = month <= 6 ? (year - 2) : (year - 1); + + const year1 = startYear; + const year2 = startYear - 1; + const year3 = startYear - 2; + const year4 = startYear - 3; + const year5 = startYear - 4; return [ { text: year1 + "년", val: year1.toString() }, { text: year2 + "년", val: year2.toString() }, @@ -173,10 +179,10 @@ const getYearData = () => { ] } -const selectSearchYear:SelectDataType[] = getYearData(); +const selectSearchYear: SelectDataType[] = getYearData(); // 유량 기간 구분 -const selectFlowTerm : SelectDataType[] = [ +const selectFlowTerm: SelectDataType[] = [ { text: "연간", val: '0' }, { text: "하절기", val: '01' }, { text: "동절기", val: '02' }, @@ -185,15 +191,15 @@ const selectFlowTerm : SelectDataType[] = [ ]; // 유량 기간 구분 -const selectFlowPanel : SelectDataType[] = [ - { text: "전체", val: '0'}, - { text: "3~10mm미만", val: '2'}, - { text: "10~20mm미만", val: '3'}, - { text: "20~30mm미만", val: '4'}, - { text: "30~40mm미만", val: '5'}, - { text: "40~50mm미만", val: '6'}, - { text: "50~60mm미만", val: '7'}, - { text: "60mm이상", val: '8'}, +const selectFlowPanel: SelectDataType[] = [ + { text: "전체", val: '0' }, + { text: "3~10mm미만", val: '2' }, + { text: "10~20mm미만", val: '3' }, + { text: "20~30mm미만", val: '4' }, + { text: "30~40mm미만", val: '5' }, + { text: "40~50mm미만", val: '6' }, + { text: "50~60mm미만", val: '7' }, + { text: "60mm이상", val: '8' }, ]; // 중권역 데이터 @@ -220,9 +226,9 @@ export const roundUp = (value: number, precision: number = 1): number => { * @param day : 일수 * @param digit : 소수점 자리수 */ -export const qltyDataSetting = (value: number, day : number, digit: number) => { - const toZero = digit === 1 ? '0.0' : digit === 2 ? '0.00' : '0.000'; - return value > 0 ? roundUp((value/day), digit).toFixed(digit) : toZero; +export const qltyDataSetting = (value: number, day: number, digit: number) => { + const toZero = digit === 1 ? '0.0' : digit === 2 ? '0.00' : '0.000'; + return value > 0 ? roundUp((value / day), digit).toFixed(digit) : toZero; }; export const COD_YEAR = 2021; @@ -234,13 +240,13 @@ export const COD_YEAR = 2021; // 처리시설 계획정보 호출 (알에스원) export const planInfoUrl = '/dc-service/api/v1/nowDmgMtncGnsvy'; -export const fetchPlanInfo = async (targetYear : string | undefined, ctpvNm : string | undefined, sggNm : string | undefined, fcltyCd : string | undefined) => { +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 (targetYear) queryParams.append('targetYear', targetYear); if (fcltyCd) queryParams.append('swtrmtFcltCd', fcltyCd); const queryString = queryParams.toString(); const url = queryString ? `${baseUrl}?${queryString}` : baseUrl; @@ -258,16 +264,16 @@ const fetchSidoData = async (): Promise => { const res = await getFetch('fo', '/addr/city'); const data = res.data; selectSidoData = [ - { text: "전체", val: '0'}, + { text: "전체", val: '0' }, ...data.map((item: sidoDataType) => ({ - text: item.sido || '', - val: String(item.adstDstrCd) || '' + text: item.sido || '', + val: String(item.adstDstrCd) || '' })) ]; return selectSidoData; } catch (error) { - console.error('시도 데이터를 가져오는데 실패했습니다:', error); - return selectSidoData; + console.error('시도 데이터를 가져오는데 실패했습니다:', error); + return selectSidoData; } }; @@ -279,10 +285,10 @@ const fetchSigunData = async (): Promise => { selectSigunData = [ { text: "전체", val: '0' }, ...data - .map((item: sigunDataType) => ({ + .map((item: sigunDataType) => ({ text: item.gugun || '', val: String(item.adstDstrCd) || '' - })) + })) ]; return selectSigunData; } catch (error) { @@ -297,7 +303,7 @@ const fetchRegionData = async (): Promise => { const res = await getFetch('fo', '/addr/sarea'); const data = res.data; return [ - { text: "전체", val: '0'}, + { text: "전체", val: '0' }, ...data.map((item: regionDataType) => ({ text: item.rvbsn || '', val: String(item.rvbsnCd) || '' @@ -317,10 +323,10 @@ const fetchMiddleRegionData = async (): Promise => { return [ { text: "전체", val: '0' }, ...data - .map((item: middleRegionDataType) => ({ - text: item.mdmbsn || '', - val: String(item.rvbsnCd) || '' - })) + .map((item: middleRegionDataType) => ({ + text: item.mdmbsn || '', + val: String(item.rvbsnCd) || '' + })) ]; } catch (error) { console.error('중권역 데이터를 가져오는데 실패했습니다:', error); @@ -336,10 +342,10 @@ const fetchUnitWaterShedData = async (): Promise => { return [ { text: "전체", val: '0' }, ...data - .map((item: unitWaterShedDataType) => ({ - text: item.lgbsn || '', - val: String(item.rvbsnCd) || '' - })) + .map((item: unitWaterShedDataType) => ({ + text: item.lgbsn || '', + val: String(item.rvbsnCd) || '' + })) ]; } catch (error) { console.error('단위유역 데이터를 가져오는데 실패했습니다:', error); @@ -355,11 +361,11 @@ const fetchEnvPartData = async (): Promise => { selectEnvPartData = [ { text: "전체", val: '0', adstDliStrCd: '' }, ...data - .map((item: envPartDataType) => ({ - text: item.lclgvrnmntNm || '', - val: String(item.lclgvrnmntCd) || '', - adstDliStrCd: item.adstDliStrCd || '' - })) + .map((item: envPartDataType) => ({ + text: item.lclgvrnmntNm || '', + val: String(item.lclgvrnmntCd) || '', + adstDliStrCd: item.adstDliStrCd || '' + })) ]; return selectEnvPartData; } catch (error) { @@ -372,7 +378,7 @@ const fetchEnvPartData = async (): Promise => { * Store - expaort ====================================*/ export type CommonAction = { - getMenuAuth : (menuCd : number) => Promise; + getMenuAuth: (menuCd: number) => Promise; initializeCommonData: () => Promise; } @@ -394,7 +400,7 @@ export type CommonType = { selectFlowPanel: SelectDataType[]; selectEnvPartData: envPartSelectDataType[]; btnClass: string; - COD_YEAR : number; + COD_YEAR: number; }; auth: { @@ -424,7 +430,7 @@ export const commonState: CommonType = { selectFlowPanel: selectFlowPanel, selectEnvPartData: selectEnvPartData, btnClass: "p-4 m-2 !mr-10 text-white rounded-sm text-lg font-medium", - COD_YEAR : COD_YEAR, + COD_YEAR: COD_YEAR, }, auth: { @@ -436,10 +442,12 @@ export const commonState: CommonType = { }, }; -export const CommonReducer:(set:(fn: (state: CommonType) => CommonType) => void)=>CommonAction=(set: (fn: (state: CommonType) => CommonType) => void) => { +export const CommonReducer = ( + set: (fn: (state: CommonType) => CommonType) => void +): CommonAction => { return { // 메뉴 권한 확인 - getMenuAuth : async (menuCd : number) =>{ + getMenuAuth: async (menuCd: number) => { const response = await getFetch( "local", `/cms-service/api/v1/menu-authrts/pageinfo/${menuCd}` diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 60267e388..d3f3e3e05 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -1289,7 +1289,9 @@ const searchWaterUsage = async (searchYear: string, fcltyCd: string) => { return waterUsage; } -export const dashBoardReducer: (set: (fn: (state: DashBoardType) => DashBoardType) => void) => DashBoardActions = (set: (fn: (state: DashBoardType) => DashBoardType) => void) => { +export const dashBoardReducer = ( + set: (fn: (state: DashBoardType) => DashBoardType) => void +): DashBoardActions => { return { initializeDashBoardData: async () => { set((state: DashBoardType) => ({ @@ -1311,7 +1313,7 @@ export const dashBoardReducer: (set: (fn: (state: DashBoardType) => DashBoardTyp }, })); let waterUsage = [0, 0, 0]; - waterUsage = await searchWaterUsage(targetYear, fcltyCd); + waterUsage = await searchWaterUsage(targetYear, fcltyCd); // /fclt/flow/{fcltyCd}/{year} set((state: DashBoardType) => ({ ...state, @@ -1323,8 +1325,7 @@ export const dashBoardReducer: (set: (fn: (state: DashBoardType) => DashBoardTyp }, })); - const res = await fetchFacilityPlan(targetYear, fcltyCd, set); - + const res = await fetchFacilityPlan(targetYear, fcltyCd, set); // /dc-service/api/v1/nowDmgMtncGnsvy let minDiff = 9999999; let minIndex; res.forEach((el: any, idx) => { diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index f62831959..a0b421db8 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -263,9 +263,7 @@ export function UiTable({ item.visible != false).length - - headlist.filter( - (item) => item.visible != false && item.colSpan, - ).length + headlist.filter((item) => item.visible != false && item.colSpan).length } className="h-24 text-center text-gray-500" >