Dashboard 1차 완료(링크 연결 남음)

thkim
Lim\jun 2024-03-04 17:34:43 +09:00
parent 5b49f4ec85
commit e333191efd
5 changed files with 173 additions and 188 deletions

View File

@ -1,24 +1,18 @@
import PropTypes from 'prop-types';
import { useState } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { Link as RouterLink } from 'react-router-dom';
// material-ui
import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
import * as EgovNet from 'api/egovFetch';
import {itemIdxByPage} from "../../../utils/calc";
import {format} from "date-fns";
function createData(trackingNo, title, dt, name) {
return { trackingNo, title, dt, name };
}
const rows = [
createData(1, '흙막이 가시설 띠장 전단 설계시 플래지 ...', '2024-02-04 13:22', '홍길동'),
createData(2, '콘크리트 벽체 설계기준 적용 유무 확인 ...', '2024-02-04 13:22', '홍길동'),
createData(3, '한중콘크리트 초기양생 관련', '2024-02-04 13:22', '홍길동'),
createData(4, 'KDS 21 30 00 : 2022가설흙...', '2024-02-04 13:22', '홍길동'),
createData(5, '인테리어필름 시방서 관련', '2024-02-04 13:22', '홍길동'),
createData(6, '고온고압증기양생기포콘크리트(ALC) 구조', '2024-02-04 13:22', '홍길동'),
createData(7, '지반을 최저등급으로 가정한 경우란', '2024-02-04 13:22', '홍길동')
];
function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy]) {
return -1;
@ -110,6 +104,68 @@ export default function OrderTable() {
const [orderBy] = useState('trackingNo');
const [selected] = useState([]);
const [listTag, setListTag] = useState([]);
const retrieveList = useCallback(() => {
// console.groupCollapsed("EgovAdminUsageList.retrieveList()");
const retrieveListURL = '/admin/dashboard/question';
const requestOptions = {
method: "POST",
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify()
}
EgovNet.requestFetch(retrieveListURL,
requestOptions,
(resp) => {
let mutListTag = [];
const resultCnt = parseInt(resp.result.QuestionList.length);
// const currentPageNo = 1; // resp.result.paginationInfo.currentPageNo;
// const pageSize = resultCnt; // resp.result.paginationInfo.pageSize;
//
if (resultCnt === 0) {
mutListTag.push(createData('', '데이터가 없습니다.', '', ''));
} else {
resp.result.QuestionList.forEach(function (item, index) {
if (index === 0) mutListTag = []; //
// const listIdx = itemIdxByPage(resultCnt, currentPageNo, pageSize, index);
mutListTag.push(
createData(index+1, item[0], item[1], item[2]),
);
});
}
setListTag(mutListTag);
},
function (resp) {
console.log("err response : ", resp);
}
);
// console.groupEnd("EgovAdminPrivacyList.retrieveList()");
// eslint-disable-next-line react-hooks/exhaustive-deps
},[listTag]);
useEffect(() => {
retrieveList();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// const rows = [listTag
// createData(1, ' ...', '2024-02-04 13:22', ''),
// createData(2, ' ...', '2024-02-04 13:22', ''),
// createData(3, ' ', '2024-02-04 13:22', ''),
// createData(4, 'KDS 21 30 00 : 2022...', '2024-02-04 13:22', ''),
// createData(5, ' ', '2024-02-04 13:22', ''),
// createData(6, '(ALC) ', '2024-02-04 13:22', ''),
// createData(7, ' ', '2024-02-04 13:22', '')
// ];
const isSelected = (trackingNo) => selected.indexOf(trackingNo) !== -1;
return (
@ -137,7 +193,7 @@ export default function OrderTable() {
>
<OrderTableHead order={order} orderBy={orderBy} />
<TableBody>
{stableSort(rows, getComparator(order, orderBy)).map((row, index) => {
{stableSort(listTag, getComparator(order, orderBy)).map((row, index) => {
const isItemSelected = isSelected(row.trackingNo);
const labelId = `enhanced-table-checkbox-${index}`;
@ -153,7 +209,7 @@ export default function OrderTable() {
>
<TableCell width="10%" align="left" component="th" id={labelId} scope="row">{row.trackingNo}</TableCell>
<TableCell width="50%" align="left"><Link color="secondary" component={RouterLink} to="" sx={{ overflow: 'hidden', textOverflow: 'ellipsis', display: 'block'}}>{row.title}</Link></TableCell>
<TableCell width="25%" align="center">{row.dt}</TableCell>
<TableCell width="25%" align="center">{row.dt? format(row.dt, "yyyy-MM-dd HH:mm") : ""}</TableCell>
<TableCell width="15%" align="center">{row.name}</TableCell>
</TableRow>
);

View File

@ -1,11 +1,8 @@
import React, {useState, useEffect, useCallback} from 'react'; // PureComponent
import {Link} from 'react-router-dom'; //useLocation
// import {BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
import * as EgovNet from 'api/egovFetch';
import URL from 'constants/url';
// import CODE from 'constants/code';
// material-ui
import { Box, Button, Grid, Stack, Typography } from '@mui/material';
@ -27,34 +24,12 @@ function EgovAdminDashboard(props) {
// console.log("EgovAdminScheduleList [location] : ", location);
const DATE = new Date();
// const TODAY = new Date(DATE.getFullYear(), DATE.getMonth(), DATE.getDate());
//
// const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || {schdulSe: '', year: TODAY.getFullYear(), month: TODAY.getMonth(), date: TODAY.getDate()});
// const [calendarTag, setCalendarTag] = useState([]);
// const innerConsole = (...args) => {
// console.log(...args);
// }
// const changeDate = (target, amount) => {
// let changedDate;
//
// if (target === CODE.DATE_YEAR) {
// changedDate = new Date(searchCondition.year + amount, searchCondition.month, searchCondition.date);
// }
//
// if (target === CODE.DATE_MONTH) {
// changedDate = new Date(searchCondition.year, searchCondition.month + amount, searchCondition.date);
// }
// setSearchCondition({...searchCondition, year: changedDate.getFullYear(), month: changedDate.getMonth(), date: changedDate.getDate()});
// }
// const [countTag, setCountTag] = useState([]);
const [dashboardCnt, setDashboardCnt] = useState({
ConnMonthlyCount: [[0, 0.0, 0]],
DocuMonthlyCount: [[0, 0.0, 0]]
ErrorMonthlyCount: [[0, 0.0, 0]],
DocuMonthlyCount: [[0, 0.0, 0]],
CompMonthlyCount: [[0, 0.0, 0]]
});
// const [item0, setItem0] = useState([]);
const retrieveList = useCallback(() => {
const retrieveListURL = '/admin/dashboard/dash-count';
@ -69,21 +44,8 @@ function EgovAdminDashboard(props) {
EgovNet.requestFetch(retrieveListURL,
requestOptions,
(resp) => {
// let mutCountTag = [];
setDashboardCnt(resp.result);
console.log(resp.result.ConnMonthlyCount);
// mutCountTag.push(
// <div key={listIdx} className="list_item">
// <div>{listIdx}</div>
// <div>{item.userId}</div>
// <div>{item.targetUserId}</div>
// <div>{item.accessType === "PRV_LIST" ? " " : item.accessType === "PRV_VIEW" ? "User " : "User "}</div>
// <div>{item.ipAddress}</div>
// <div>{item.accessDt}</div>
// </div>
// );
// setCountTag(mutCountTag);
// console.log(resp.result.CompMonthlyCount);
},
function (resp) {
console.log("err response : ", resp);
@ -92,123 +54,10 @@ function EgovAdminDashboard(props) {
// eslint-disable-next-lie react-hooks/exhaustive-deps
}, []);
// const Location = React.memo(function Location() {
// return (
// <div className="location">
// <ul>
// <li><Link to={URL.MAIN} className="home">Home</Link></li>
// <li><Link to={URL.ADMIN}></Link></li>
// <li>Dashboard</li>
// </ul>
// </div>
// )
// });
useEffect(() => {
retrieveList();
}, [retrieveList]);
// const [dailyUserLogList, setDailyUserLogList] = useState([]);
// const [isDailyChart, setIsDailyChart] = useState(true);
//
// const getDailyUserLogList = useCallback(() => {
// // console.groupCollapsed("EgovAdminScheduleList.getDailyUserLogList()");
// //
// // console.log("@@@ isDailyChart : " + isDailyChart);
//
// const dailyUserLogListURL = isDailyChart ? '/admin/dashboard/daily-user-log-list' : '/admin/dashboard/monthly-user-log-list';
//
// const requestOptions = {
// method: "GET",
// headers: {
// 'Content-type': 'application/json',
// }
// }
//
// EgovNet.requestFetch(dailyUserLogListURL,
// requestOptions,
// (resp) => {
// setDailyUserLogList(resp.result.dailyUserLogList);
// // console.log("@@@ : " + dailyUserLogList);
// },
// function (resp) {
// // console.log("err response : ", resp);
// }
// );
// // console.groupEnd("EgovAdminScheduleList.getDailyUserLogList()");
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [isDailyChart]);
//
// useEffect(() => {
// getDailyUserLogList();
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [isDailyChart]);
//
// const handleChartToggle = () => {
// setIsDailyChart(!isDailyChart);
// };
//
// const ChartToggle = ({onToggle}) => {
//
// const handleToggle = () => {
// onToggle(!isDailyChart);
// };
//
// return (
// <button onClick={handleToggle}>
// {isDailyChart ? '' : ''}
// </button>
// )
// }
//
// const data = dailyUserLogList.map(item => ({
// logDt: item.logDt,
// uv: item.mobileCnt,
// " ": item.logCnt,
// amt: item.pcCnt,
// }));
//
// const CustomTooltip = ({active, payload, label}) => {
// if (active && payload && payload.length) {
// return (
// <div className="custom-tooltip">
// <p className="desc"> </p>
// <p className="label">{`${label} : ${payload[0].value}`}</p>
// </div>
// );
// }
//
// return null;
// };
// class UserLogChart extends PureComponent {
// render() {
// return (
// <ResponsiveContainer width="100%" height="100%">
// <BarChart
// width={500}
// height={300}
// data={data}
// margin={{
// top: 5,
// right: 30,
// left: 20,
// bottom: 5,
// }}
// >
// <CartesianGrid strokeDasharray="3 3"/>
// <XAxis dataKey="logDt"/>
// <YAxis/>
// <Tooltip content={<CustomTooltip/>}/>
// <Legend/>
// <Bar dataKey=" " barSize={20} fill="#87CEFA"/>
// </BarChart>
// </ResponsiveContainer>
// );
// }
// }
// console.log("------------------------------EgovAdminScheduleList [End]");
// console.groupEnd("EgovAdminScheduleList");
@ -255,13 +104,13 @@ function EgovAdminDashboard(props) {
<AnalyticEcommerce title={`총접속자수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.ConnMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.ConnMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.ConnMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0} color={dashboardCnt.ConnMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title={`건설기준 오류건수 (${DATE.getMonth() + 1}월)`} count="78,250" percentage={70.5} extra="8,900" />
<AnalyticEcommerce title={`건설기준 오류건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.ErrorMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.ErrorMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.ErrorMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.ErrorMonthlyCount[0]?.[1] < 0} color={dashboardCnt.ErrorMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title={`기준코드 등록건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.DocuMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.DocuMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.DocuMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0} color={dashboardCnt.DocuMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title={`민원건수 (${DATE.getMonth() + 1}월)`} count="5" percentage={80} extra="1" isLoss color="warning" />
<AnalyticEcommerce title={`민원건수 (${DATE.getMonth() + 1}월)`} count={dashboardCnt.CompMonthlyCount[0]?.[0]?.toLocaleString() || '0'} percentage={parseFloat(dashboardCnt.CompMonthlyCount[0]?.[1]) || 0} extra={dashboardCnt.CompMonthlyCount[0]?.[2]?.toLocaleString() || '0'} isLoss={dashboardCnt.CompMonthlyCount[0]?.[1] < 0} color={dashboardCnt.CompMonthlyCount[0]?.[1] < 0 ? "warning" : "primary"} />
</Grid>
<Grid item md={8} sx={{ display: { sm: 'none', md: 'block', lg: 'none' } }} />

View File

@ -44,9 +44,9 @@ public class AdminDashboardController extends BaseController {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("ConnMonthlyCount", adminDashboardService.selectConnMonthly());
resultMap.put("DocuMonthlyCount", adminDashboardService.selectDocuMonthly());
// resultMap.put("loginMonthlyList", adminDashboardService.selectLoginMonthly());
// resultMap.put("loginDailyList", adminDashboardService.selectLoginDaily());
resultMap.put("ErrorMonthlyCount", adminDashboardService.selectErrorMonthly());
resultMap.put("DocuMonthlyCount", adminDashboardService.selectDocumentMonthly());
resultMap.put("CompMonthlyCount", adminDashboardService.selectComplaintMonthly());
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
@ -108,6 +108,31 @@ public class AdminDashboardController extends BaseController {
}
@Operation(
summary = "미답변 문의사항 조회",
description = "미답변 문의사항 조회",
tags = {"AdminDashboardController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@RequestMapping(method = RequestMethod.POST, value = "/question", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResultVO getBbs(@AuthenticationPrincipal LoginVO user)
throws Exception {
ResultVO resultVO = new ResultVO();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("QuestionList", adminDashboardService.selectQuestion());
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
resultVO.setResult(resultMap);
return resultVO;
}
@Operation(
summary = "해당월 접속방법 조회",
description = "해당월 PC/MOBILE 조회",

View File

@ -32,6 +32,33 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
"FROM this_month_logs, last_month_logs", nativeQuery = true)
List<Object[]> ConnMonthlyCount();
@Query(value = "WITH this_month_logs AS ( " +
" SELECT count(*) AS this_month_cnt " +
" FROM tn_document_content " +
" WHERE use_yn = 'Y' AND COALESCE(error_cd, '') <> '' " +
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
"), " +
"last_month_logs AS ( " +
" SELECT count(*) AS last_month_cnt " +
" FROM tn_document_content " +
" WHERE use_yn = 'Y' AND COALESCE(error_cd, '') <> '' " +
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
") " +
"SELECT " +
" this_month_cnt, " +
" CASE " +
" WHEN last_month_cnt = 0 AND this_month_cnt = 0 THEN 0" +
" WHEN last_month_cnt = 0 THEN 100" +
" ELSE ROUND(((CAST(this_month_cnt AS NUMERIC) - last_month_cnt) / last_month_cnt * 100), 1)" +
" END AS ratio, " +
" last_month_cnt " +
"FROM this_month_logs, last_month_logs", nativeQuery = true)
List<Object[]> ErrorMonthlyCount();
@Query(value = "WITH this_month_logs AS ( " +
" SELECT count(*) AS this_month_cnt " +
" FROM tn_document_info " +
@ -57,6 +84,33 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
"FROM this_month_logs, last_month_logs", nativeQuery = true)
List<Object[]> DocuMonthlyCount();
@Query(value = "WITH this_month_logs AS ( " +
" SELECT count(*) AS this_month_cnt " +
" FROM tn_bbs_contents " +
" WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' " +
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE) " +
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) + INTERVAL '1 month' " +
"), " +
"last_month_logs AS ( " +
" SELECT count(*) AS last_month_cnt " +
" FROM tn_bbs_contents " +
" WHERE bbs_id = 'KCSC-QA'AND use_yn = 'Y' " +
" AND frst_crt_dt >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') " +
" AND frst_crt_dt < DATE_TRUNC('month', CURRENT_DATE) " +
") " +
"SELECT " +
" this_month_cnt, " +
" CASE " +
" WHEN last_month_cnt = 0 AND this_month_cnt = 0 THEN 0" +
" WHEN last_month_cnt = 0 THEN 100" +
" ELSE ROUND(((CAST(this_month_cnt AS NUMERIC) - last_month_cnt) / last_month_cnt * 100), 1) " +
" END AS ratio, " +
" last_month_cnt " +
"FROM this_month_logs, last_month_logs", nativeQuery = true)
List<Object[]> CompMonthlyCount();
@Query(value = "WITH all_months AS (" +
" SELECT generate_series(DATE_TRUNC('year', CURRENT_DATE), DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '11 month', INTERVAL '1 month') AS month_start" +
")" +
@ -97,7 +151,6 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
List<Long> LoginMonthlyList();
@Query(value = "WITH all_days AS (" +
" SELECT generate_series(" +
" DATE_TRUNC('year', CURRENT_DATE)," +
@ -113,7 +166,6 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
List<Long> LoginDailyList();
@Query(value = "WITH all_days AS (" +
" SELECT generate_series(" +
" DATE_TRUNC('year', CURRENT_DATE)," +
@ -130,6 +182,13 @@ public interface DashboardRepository extends JpaRepository<TnDailyMenuLog, Long>
List<Long> FileDailyList();
@Query(value = "SELECT bbs_cont_title, frst_crt_dt, frst_crt_id " +
"FROM tn_bbs_contents a " +
"WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' " +
"AND (SELECT bbs_cont_seq b FROM public.tn_bbs_contents b WHERE bbs_id = 'KCSC-QA' AND use_yn = 'Y' AND b.bbs_cont_seq_group=a.bbs_cont_seq) IS NULL " +
"ORDER BY frst_crt_dt desc", nativeQuery = true)
List<Object[]> QuestionList();
@Query(value = "SELECT sum(pc_cnt) AS p_cnt, sum(mobile_cnt) AS m_cnt " +
"FROM tn_daily_user_log " +

View File

@ -1,25 +1,25 @@
package com.dbnt.kcscbackend.admin.dashboard.service;
//import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
//import com.dbnt.kcscbackend.admin.dashboard.repository.TnDailyUserLogRepository;
//import com.dbnt.kcscbackend.admin.boards.entity.TnBbsContents;
import com.dbnt.kcscbackend.admin.dashboard.repository.DashboardRepository;
import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
//import java.time.LocalDate;
import java.util.List;
@Service
@RequiredArgsConstructor
public class AdminDashboardService extends EgovAbstractServiceImpl {
// private final TnDailyUserLogRepository tnDailyUserLogRepository;
private final DashboardRepository dashboardRepository;
public List<Object[]> selectConnMonthly() { return dashboardRepository.ConnMonthlyCount(); }
public List<Object[]> selectDocuMonthly() { return dashboardRepository.DocuMonthlyCount(); }
public List<Object[]> selectErrorMonthly() { return dashboardRepository.ErrorMonthlyCount(); }
public List<Object[]> selectDocumentMonthly() { return dashboardRepository.DocuMonthlyCount(); }
public List<Object[]> selectComplaintMonthly() { return dashboardRepository.CompMonthlyCount(); }
public List<Long> selectMenuMonthly() { return dashboardRepository.MenuMonthlyList(); }
@ -31,13 +31,9 @@ public class AdminDashboardService extends EgovAbstractServiceImpl {
public List<Long> selectFileDaily() { return dashboardRepository.FileDailyList(); }
public List<Object[]> selectQuestion() { return dashboardRepository.QuestionList(); }
public List<Object[]> selectConnectMonthly() { return dashboardRepository.findConnMonthly(); }
// public List<TnDailyUserLog> selectDailyUserLogList(LocalDate startDate, LocalDate endDate) {
// return tnDailyUserLogRepository.findByLogDtBetweenOrderByLogDt(startDate, endDate);
// }
//
// public List<Object[]> selectMonthlyUserLogList(LocalDate startDate, LocalDate endDate) {
// return tnDailyUserLogRepository.selectMonthlyUserLogStatistics(startDate, endDate);
// }
}