diff --git a/egovframe-template-simple-react-contribution/src/css/page.css b/egovframe-template-simple-react-contribution/src/css/page.css index c993903..4413141 100644 --- a/egovframe-template-simple-react-contribution/src/css/page.css +++ b/egovframe-template-simple-react-contribution/src/css/page.css @@ -170,22 +170,16 @@ .userList .result .list_item > div:nth-child(7) {width: 100px;} /* 사이트관리 > 환경설정 > 메뉴관리 */ - .menuList .head > span:nth-child(1) {width: 100px;} - .menuList .head > span:nth-child(2) {width: 150px;} - .menuList .head > span:nth-child(3) {width: 100px;} - .menuList .head > span:nth-child(4) {width: 60px;} - .menuList .head > span:nth-child(5) {width: 60px;} - .menuList .head > span:nth-child(6) {width: 200px;} - .menuList .head > span:nth-child(7) {width: 100px;} - .menuList .head > span:nth-child(8) {width: 100px;} - .menuList .result .list_item > div:nth-child(1) {width: 100px;} - .menuList .result .list_item > div:nth-child(2) {width: 150px;} - .menuList .result .list_item > div:nth-child(3) {width: 100px;} - .menuList .result .list_item > div:nth-child(4) {width: 60px;} - .menuList .result .list_item > div:nth-child(5) {width: 60px;} - .menuList .result .list_item > div:nth-child(6) {width: 200px;} - .menuList .result .list_item > div:nth-child(7) {width: 100px;} - .menuList .result .list_item > div:nth-child(8) {width: 100px;} + .menuList .head > span:nth-child(1) {width: 120px;} + .menuList .head > span:nth-child(2) {width: 100px;} + .menuList .head > span:nth-child(3) {width: 200px;} + .menuList .head > span:nth-child(4) {width: 100px;} + .menuList .head > span:nth-child(5) {width: 100px;} + .menuList .result .list_item > div:nth-child(1) {width: 120px;} + .menuList .result .list_item > div:nth-child(2) {width: 100px;} + .menuList .result .list_item > div:nth-child(3) {width: 200px;} + .menuList .result .list_item > div:nth-child(4) {width: 100px;} + .menuList .result .list_item > div:nth-child(5) {width: 100px;} /* 사이트관리 > 환경설정 > 메뉴권한관리 */ .roleList .head > span:nth-child(1) {width: 120px;} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx index 78d62b7..b26d352 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/MenuMgt.jsx @@ -33,11 +33,8 @@ function MenuMgt({}) { resp.result.menuList.forEach(function (item, index) { mutListTag.push(
-
{item.menuId}
+
{item.menuGroup?'└ ':''}{item.menuId}
{item.menuTitle}
-
{item.menuGroup}
-
{item.menuLevel}
-
{item.menuSort}
{item.menuUrl}
{item.menuTypeValue}
@@ -90,10 +87,7 @@ function MenuMgt({}) {
메뉴 코드 메뉴 이름 - 부모 메뉴 - 레벨 - 정렬 - URI + 경로 타입 diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx index 55087f8..fc4ed07 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/menuMgt/MenuModal.jsx @@ -38,7 +38,7 @@ function MenuModal({savedInfo, reloadFunction}){ }else if(Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)){ console.log("토큰 갱신중.") }else{ - alert(resp.result.resultMessage) + alert(resp.resultMessage) } } ) @@ -78,6 +78,14 @@ function MenuModal({savedInfo, reloadFunction}){
{editMenu(e)}} noValidate> + + + 그룹 코드 + + + + + 메뉴 코드 @@ -94,15 +102,7 @@ function MenuModal({savedInfo, reloadFunction}){ - - - 부모 메뉴 - - - - - - + 레벨 @@ -110,7 +110,7 @@ function MenuModal({savedInfo, reloadFunction}){ - + 정렬 @@ -120,7 +120,7 @@ function MenuModal({savedInfo, reloadFunction}){ - URI + 경로 diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx index 0351568..1d633ef 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/logs/PrivacyLogs.jsx @@ -8,6 +8,7 @@ import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; import EgovPaging from 'components/EgovPaging'; import { itemIdxByPage } from 'utils/calc'; +import {format} from "date-fns"; function PrivacyConnections(props) { // console.group("EgovAdminPrivacyList"); @@ -66,7 +67,7 @@ function PrivacyConnections(props) {
{item.targetUserId}
{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}
{item.ipAddress}
-
{item.accessDt}
+
{item.accessDt ? format(item.accessDt, "yyyy-MM-dd HH:mm") : ""}
); } @@ -122,7 +123,7 @@ function PrivacyConnections(props) { 수정 ID 타입 접속IP - 변경일자 + 일자
{listTag} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/schedule/BbsTable.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/schedule/BbsTable.jsx index ce00415..b358800 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/schedule/BbsTable.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/schedule/BbsTable.jsx @@ -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() { > - {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() { > {row.trackingNo} {row.title} - {row.dt} + {row.dt? format(row.dt, "yyyy-MM-dd HH:mm") : ""} {row.name} ); diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/schedule/EgovAdminScheduleList.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/schedule/EgovAdminScheduleList.jsx index 7879d2e..c46bcc2 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/schedule/EgovAdminScheduleList.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/schedule/EgovAdminScheduleList.jsx @@ -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( - //
- //
{listIdx}
- //
{item.userId}
- //
{item.targetUserId}
- //
{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}
- //
{item.ipAddress}
- //
{item.accessDt}
- //
- // ); - // 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 ( - //
- //
    - //
  • Home
  • - //
  • 사이트관리
  • - //
  • Dashboard
  • - //
- //
- // ) - // }); - 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 ( - // - // ) - // } - // - // 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 ( - //
- //

사용자 접속 현황

- //

{`${label} : ${payload[0].value}`}

- //
- // ); - // } - // - // return null; - // }; - - // class UserLogChart extends PureComponent { - // render() { - // return ( - // - // - // - // - // - // }/> - // - // - // - // - // ); - // } - // } - // console.log("------------------------------EgovAdminScheduleList [End]"); // console.groupEnd("EgovAdminScheduleList"); @@ -255,13 +104,13 @@ function EgovAdminDashboard(props) { - + - + diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx index 4251f33..39e9d00 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/users/List.jsx @@ -64,10 +64,6 @@ function List({}) { ); },[]); - useEffect(() => { - retrieveList(searchCondition); - }, []); - useEffect(() => { retrieveList(searchCondition); }, [searchCondition.pageIndex]); diff --git a/egovframe-template-simple-react-contribution/src/pages/standardCode/list/HistoryModal.jsx b/egovframe-template-simple-react-contribution/src/pages/standardCode/list/HistoryModal.jsx index 9092dfa..f2a5114 100644 --- a/egovframe-template-simple-react-contribution/src/pages/standardCode/list/HistoryModal.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/standardCode/list/HistoryModal.jsx @@ -1,13 +1,9 @@ import React from "react"; -import { SERVER_URL } from 'config'; +import * as File from "utils/file" import {Button, Modal, Nav} from "react-bootstrap"; function HistoryModal({closeFn, standardCode}){ - function fileDownload(fileSeq){ - window.open(encodeURI(SERVER_URL+'/file/download?fileSeq='+fileSeq)); - } - return( <> @@ -30,11 +26,11 @@ function HistoryModal({closeFn, standardCode}){
{history.rvsnYmd.split('T')[0]}
{history.docFileGrpId} - {history.docFileGrpId?:''} + {history.docFileGrpId?:''}
{history.rvsnFileGrpId} - {history.rvsnFileGrpId?:''} + {history.rvsnFileGrpId?:''}
) diff --git a/egovframe-template-simple-react-contribution/src/pages/standardCode/viewer/CodeViewer.jsx b/egovframe-template-simple-react-contribution/src/pages/standardCode/viewer/CodeViewer.jsx index 9423951..70ef815 100644 --- a/egovframe-template-simple-react-contribution/src/pages/standardCode/viewer/CodeViewer.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/standardCode/viewer/CodeViewer.jsx @@ -1,9 +1,7 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useLocation, useParams } from 'react-router-dom'; -import SbItem from './SbItem' import Loading from 'components/Loading' import BookmarkModal from './BookmarkModal'; -import {SbContainer} from './Sb.style' import {VwDiv, VwPtag} from './Vw.style' import Form from 'react-bootstrap/Form' import Row from 'react-bootstrap/Row'; @@ -16,6 +14,7 @@ import {parseJwt} from "utils/parseJwt"; import Button from "react-bootstrap/Button"; import {InputGroup} from "react-bootstrap"; import ViewerTree from "./ViewerTree"; +import * as File from "utils/file"; function CodeViewer(props) { const [treeLoading, setTreeLoading] = useState(true); @@ -73,6 +72,8 @@ function CodeViewer(props) { let optionTag = []; let activeIndex = 0; let docTitle = ""; + let docFileGrpId = ""; + let rvsnFileGrpId = ""; if(ymd===undefined){ activeIndex = docInfo.length-1 docTitle = docInfo[docInfo.length-1].doc_nm @@ -95,7 +96,10 @@ function CodeViewer(props) { if(index === activeIndex){ buttonClass += "docInfoActive" pClass += "yearInfoActive" + docFileGrpId = item.doc_file_grp_id; + rvsnFileGrpId = item.rvsn_file_grp_id; } + optionTag.push( {item.doc_yr}

) }) - headTag.push({docCode} {docTitle}{optionTag}) + headTag.push( + <> + + + {docCode} {docTitle} + {optionTag} + + + + + + {rvsnFileGrpId?{File.download(rvsnFileGrpId)}}/>:''} + {docFileGrpId?{File.standardCode(docFileGrpId)}}/>:''} + + + ) }else{ headTag.push(
검색된 결과가 없습니다.
); // 코드 목록 초기값 } @@ -409,13 +428,7 @@ function CodeViewer(props) { - {docInfo} - - - - - - + {docInfo} diff --git a/egovframe-template-simple-react-contribution/src/utils/file.jsx b/egovframe-template-simple-react-contribution/src/utils/file.jsx new file mode 100644 index 0000000..678ff4b --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/utils/file.jsx @@ -0,0 +1,11 @@ +import {SERVER_URL} from "../config"; +import {parseJwt} from "./parseJwt"; +import {getLocalItem} from "./storage"; + +export function download(fileSeq){ + window.open(encodeURI(SERVER_URL+'/file/download?fileSeq='+fileSeq)); +} +export function standardCode(fileSeq){ + const sessionUser = parseJwt(getLocalItem('accessToken')); + window.open(encodeURI(SERVER_URL+'/file/standardCode-download?userId='+sessionUser?.id+'&fileSeq='+fileSeq)); +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java index 0a65294..a310df2 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/entity/TcMenu.java @@ -35,7 +35,7 @@ public class TcMenu { @Column(name = "menu_sort") private Integer menuSort; @Column(name = "menu_url") - @NotBlank(message = "메뉴URI를 입력해주세요.") + @NotBlank(message = "경로를 입력해주세요.") private String menuUrl; @Column(name = "menu_type_cd") @NotBlank(message = "타입을 선택해주세요.") diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/AdminDashboardController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/AdminDashboardController.java index 4f29c2f..315ff44 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/AdminDashboardController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/AdminDashboardController.java @@ -44,9 +44,9 @@ public class AdminDashboardController extends BaseController { Map 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 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 조회", diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/repository/DashboardRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/repository/DashboardRepository.java index afa8cc6..d969f86 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/repository/DashboardRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/repository/DashboardRepository.java @@ -32,6 +32,33 @@ public interface DashboardRepository extends JpaRepository "FROM this_month_logs, last_month_logs", nativeQuery = true) List 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 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 "FROM this_month_logs, last_month_logs", nativeQuery = true) List 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 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 List LoginMonthlyList(); - @Query(value = "WITH all_days AS (" + " SELECT generate_series(" + " DATE_TRUNC('year', CURRENT_DATE)," + @@ -113,7 +166,6 @@ public interface DashboardRepository extends JpaRepository List LoginDailyList(); - @Query(value = "WITH all_days AS (" + " SELECT generate_series(" + " DATE_TRUNC('year', CURRENT_DATE)," + @@ -130,6 +182,13 @@ public interface DashboardRepository extends JpaRepository List 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 QuestionList(); + @Query(value = "SELECT sum(pc_cnt) AS p_cnt, sum(mobile_cnt) AS m_cnt " + "FROM tn_daily_user_log " + diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/service/AdminDashboardService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/service/AdminDashboardService.java index bee8ac1..1061a04 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/service/AdminDashboardService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/dashboard/service/AdminDashboardService.java @@ -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 selectConnMonthly() { return dashboardRepository.ConnMonthlyCount(); } - public List selectDocuMonthly() { return dashboardRepository.DocuMonthlyCount(); } + public List selectErrorMonthly() { return dashboardRepository.ErrorMonthlyCount(); } + + public List selectDocumentMonthly() { return dashboardRepository.DocuMonthlyCount(); } + + public List selectComplaintMonthly() { return dashboardRepository.CompMonthlyCount(); } public List selectMenuMonthly() { return dashboardRepository.MenuMonthlyList(); } @@ -31,13 +31,9 @@ public class AdminDashboardService extends EgovAbstractServiceImpl { public List selectFileDaily() { return dashboardRepository.FileDailyList(); } + public List selectQuestion() { return dashboardRepository.QuestionList(); } + public List selectConnectMonthly() { return dashboardRepository.findConnMonthly(); } -// public List selectDailyUserLogList(LocalDate startDate, LocalDate endDate) { -// return tnDailyUserLogRepository.findByLogDtBetweenOrderByLogDt(startDate, endDate); -// } -// -// public List selectMonthlyUserLogList(LocalDate startDate, LocalDate endDate) { -// return tnDailyUserLogRepository.selectMonthlyUserLogStatistics(startDate, endDate); -// } + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java index 74ec53a..5dfc362 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThAttachFileLog.java @@ -9,8 +9,6 @@ import org.hibernate.annotations.DynamicUpdate; import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; -import java.time.LocalDate; -import java.awt.*; import java.time.LocalDateTime; @Getter diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java index 62403e0..bea3b4c 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java @@ -3,17 +3,14 @@ package com.dbnt.kcscbackend.admin.logs.entity; import java.io.Serializable; import com.dbnt.kcscbackend.config.common.BoardParams; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.Accessors; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; -import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; -import java.time.LocalDate; import java.time.LocalDateTime; @Getter @@ -45,8 +42,7 @@ public class ThPrivacyLog extends BoardParams implements Serializable { private String ipAddress; @Column(name = "access_dt") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate accessDt; + private LocalDateTime accessDt; @Column(name = "session_id") private String sessionId; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java index e8a1c93..4a3deff 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/FileLogsRepository.java @@ -28,7 +28,8 @@ public interface FileLogsRepository extends JpaRepository + " COUNT(CASE WHEN group_cur_cd = 'O4' THEN 1 ELSE NULL END) AS CodeO4Cnt," + " COUNT(CASE WHEN group_cur_cd IN ('O5', 'O6', 'O7') THEN 1 ELSE NULL END) AS CodeO5Cnt " + "FROM th_attach_file_log " - + "WHERE access_dt BETWEEN TO_DATE(:startDate, 'YYYY-MM-DD') AND TO_DATE(:endDate, 'YYYY-MM-DD') " + + "WHERE access_dt >= TO_DATE(:startDate, 'YYYY-MM-DD') " + + "AND access_dt < TO_DATE(:endDate, 'YYYY-MM-DD') + INTERVAL '1 day' " + "GROUP BY TO_CHAR(access_dt, 'YYYY-MM-DD') " + "ORDER BY log_dt asc", nativeQuery = true) List selectCountFile(@Param("startDate") String startDate, @Param("endDate") String endDate); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java index 5ac6529..4f1b8d6 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java @@ -1,11 +1,16 @@ package com.dbnt.kcscbackend.admin.logs.service; +import com.dbnt.kcscbackend.admin.logs.entity.ThAttachFileLog; import com.dbnt.kcscbackend.admin.logs.entity.ThLoginLog; import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog; import com.dbnt.kcscbackend.admin.logs.entity.TnDailyUserLog; +import com.dbnt.kcscbackend.admin.logs.repository.FileLogsRepository; import com.dbnt.kcscbackend.admin.logs.repository.PrivacyLogsRepository; import com.dbnt.kcscbackend.admin.logs.repository.ThLoginLogRepository; import com.dbnt.kcscbackend.admin.logs.repository.UserLogsRepository; +import com.dbnt.kcscbackend.file.entity.TnAttachFile; +import com.dbnt.kcscbackend.standardCode.entity.TnDocumentInfo; +import com.dbnt.kcscbackend.standardCode.repository.TnDocumentInfoRepository; import lombok.RequiredArgsConstructor; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.springframework.stereotype.Service; @@ -24,6 +29,8 @@ public class AdminLogsService extends EgovAbstractServiceImpl { private final PrivacyLogsRepository privacyLogsRepository; private final ThLoginLogRepository loginLogRepository; private final UserLogsRepository userLogsRepository; + private final FileLogsRepository fileLogsRepository; + private final TnDocumentInfoRepository documentInfoRepository; public Map selectPrivacyList() { Map resultMap = new HashMap<>(); @@ -47,7 +54,7 @@ public class AdminLogsService extends EgovAbstractServiceImpl { public void insertPrivacyLog(String userId, String ipAddress, String accessType, String targetUserId){ ThPrivacyLog log = new ThPrivacyLog(); log.setUserId(userId); - log.setAccessDt(LocalDate.now()); + log.setAccessDt(LocalDateTime.now()); log.setIpAddress(ipAddress); log.setAccessType(accessType); log.setTargetUserId(targetUserId); @@ -93,4 +100,26 @@ public class AdminLogsService extends EgovAbstractServiceImpl { } } + + @Transactional + public void insertFileLog(TnAttachFile tnAttachFile, String accessId, String ipAddress){ + TnDocumentInfo documentInfo = documentInfoRepository.findByDocFileGrpId(tnAttachFile.getFileSeq().toString()).orElse(null); + ThAttachFileLog fileLog = new ThAttachFileLog(); + fileLog.setFileSeq((long)tnAttachFile.getFileSeq()); + fileLog.setAccessType("FILE_DOWN"); + fileLog.setAccessId(accessId); + fileLog.setAccessDt(LocalDateTime.now()); + fileLog.setIpAddress(ipAddress); + switch (documentInfo.getKcscCd().split(" ")[0]){ + case "KDS": fileLog.setGroupCurCd("10"); break; + case "KCS": fileLog.setGroupCurCd("20"); break; + case "SMCS": fileLog.setGroupCurCd("40"); break; + case "EXCS": fileLog.setGroupCurCd("50"); break; + case "KRCCS": fileLog.setGroupCurCd("60"); break; + case "KRACS": fileLog.setGroupCurCd("70"); break; + case "LHCS": fileLog.setGroupCurCd("80"); break; + case "KWCS": fileLog.setGroupCurCd("90"); break; + } + fileLogsRepository.save(fileLog); + } } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java index b202f74..85a7126 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/security/SecurityConfig.java @@ -72,6 +72,7 @@ public class SecurityConfig { "/cmm/main/**.do", // 메인페이지 "/cmm/fms/FileDown.do", //파일 다운로드 "/file/download", //파일 다운로드 + "/file/standardCode-download", //파일 다운로드 "/cmm/fms/getImage.do", //갤러리 이미지보기 "/cop/bbs/selectUserBBSMasterInfAPI.do", //게시판 마스터 상세 조회 diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/FileController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/FileController.java index 2343c72..370dc20 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/FileController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/FileController.java @@ -1,10 +1,13 @@ package com.dbnt.kcscbackend.file; +import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService; +import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.config.util.ClientUtils; import com.dbnt.kcscbackend.file.entity.TnAttachFile; import com.dbnt.kcscbackend.file.service.FileService; import com.dbnt.kcscbackend.standardCode.service.StandardCodeService; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -20,37 +23,22 @@ import java.io.*; public class FileController { private final FileService fileService; - private final StandardCodeService standardCodeService; + private final AdminLogsService adminLogsService; @RequestMapping(method = RequestMethod.GET, value = "/download") public void download(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile) throws Exception{ - tnAttachFile = fileService.selectTnAttachFile(tnAttachFile); - - if(tnAttachFile != null){ - BufferedInputStream in; - BufferedOutputStream out; - try { - File file = new File(tnAttachFile.getFilePath()); - - ClientUtils.setDisposition(tnAttachFile.getFileOldName(), request, response); - in = new BufferedInputStream(new FileInputStream(file)); - out = new BufferedOutputStream(response.getOutputStream()); - FileCopyUtils.copy(in, out); - out.flush(); - if(out!=null) out.close(); - if(in!=null )in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + fileDownload(request, response, tnAttachFile); } - @RequestMapping(method = RequestMethod.GET, value = "/standardCode/download") - public void standardCodeDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile) throws Exception{ - + @RequestMapping(method = RequestMethod.GET, value = "/standardCode-download") + public void standardCodeDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile, String userId) throws Exception{ tnAttachFile = fileService.selectTnAttachFile(tnAttachFile); + adminLogsService.insertFileLog(tnAttachFile, userId, ClientUtils.getRemoteIP(request)); + fileDownload(request, response, tnAttachFile); + } + private void fileDownload(HttpServletRequest request, HttpServletResponse response, TnAttachFile tnAttachFile){ if(tnAttachFile != null){ BufferedInputStream in; BufferedOutputStream out; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/entity/TnDocumentInfo.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/entity/TnDocumentInfo.java index 8acc2d3..53c6358 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/entity/TnDocumentInfo.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/entity/TnDocumentInfo.java @@ -1,7 +1,6 @@ package com.dbnt.kcscbackend.standardCode.entity; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -22,9 +21,9 @@ public class TnDocumentInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "doc_info_seq") - private int docInfoSeq; + private Integer docInfoSeq; @Column(name = "group_seq", nullable = false) - private int groupSeq; + private Integer groupSeq; @Column(name = "kcsc_cd") private String kcscCd; @Column(name = "old_kcsc_cd") @@ -34,7 +33,7 @@ public class TnDocumentInfo { @Column(name = "doc_yr", nullable = false) private String docYr; @Column(name = "doc_cycl", nullable = false) - private int docCycl; + private Integer docCycl; @Column(name = "doc_er", nullable = false) private String docEr; @Column(name = "estb_ymd") @@ -44,7 +43,7 @@ public class TnDocumentInfo { @Temporal(TemporalType.DATE) private Date rvsnYmd; @Column(name = "doc_rev_hist_seq") - private int docRevHistSeq; + private Integer docRevHistSeq; @Column(name = "doc_brief", length = 1000) private String docBrief; @Column(name = "doc_rvsn_remark", length = 1000) @@ -66,7 +65,7 @@ public class TnDocumentInfo { @Temporal(TemporalType.DATE) private Date aplcnEndYmd; @Column(name = "doc_order", nullable = false) - private int docOrder; + private Integer docOrder; @Column(name = "last_yn", nullable = false) private char lastYn; @Column(name = "doc_file_grp_id") diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/repository/TnDocumentInfoRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/repository/TnDocumentInfoRepository.java index 1ab2c1a..3f1050f 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/repository/TnDocumentInfoRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/standardCode/repository/TnDocumentInfoRepository.java @@ -6,8 +6,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import java.util.List; +import java.util.Optional; public interface TnDocumentInfoRepository extends JpaRepository { @Query(value = "select * from sp_get_tn_document_info_by_group_cd(null, :docCode)", nativeQuery = true) List spGetTnDocumentInfoByGroupCd(String docCode); + + Optional findByDocFileGrpId(String fileSeq); } diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml index 1b2de55..73a369e 100644 --- a/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml +++ b/kcsc-back-end/src/main/resources/mybatisMapper/AdminUsersMapper.xml @@ -17,7 +17,7 @@ inner join tc_code_item b on a.user_se = b.item_cd inner join tc_code_item c on a.status = c.item_cd - order by user_seq asc + order by user_seq desc limit #{rowCnt} offset #{firstIndex} diff --git a/kcsc-back-end/src/main/resources/mybatisMapper/StandardCodeMapper.xml b/kcsc-back-end/src/main/resources/mybatisMapper/StandardCodeMapper.xml index 7e8acab..731e4a6 100644 --- a/kcsc-back-end/src/main/resources/mybatisMapper/StandardCodeMapper.xml +++ b/kcsc-back-end/src/main/resources/mybatisMapper/StandardCodeMapper.xml @@ -78,6 +78,7 @@ and b.group_type = 'D' + order by doc_yr asc