From ff14346de4fa9e93d5bd07405d21230c7248482b Mon Sep 17 00:00:00 2001 From: "Lim\\jun" Date: Thu, 4 Jan 2024 18:33:36 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=ED=98=84=ED=99=A9=20-=20?= =?UTF-8?q?=EA=B0=9C=EC=9D=B8=EC=A0=95=EB=B3=B4=20=EB=A1=9C=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/css/component.css | 8 +- .../src/pages/admin/logs/PrivacyLogs.jsx | 142 +++++++++++++++++- .../admin/logs/AdminLogsController.java | 79 ++++++++++ .../admin/logs/entity/ThPrivacyLog.java | 99 ++++++++++++ .../admin/logs/mapper/AdminLogsMapper.java | 7 + .../repository/PrivacyLogsRepository.java | 12 ++ .../admin/logs/service/AdminLogsService.java | 39 +++++ 7 files changed, 379 insertions(+), 7 deletions(-) create mode 100644 kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java create mode 100644 kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java create mode 100644 kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/mapper/AdminLogsMapper.java create mode 100644 kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/PrivacyLogsRepository.java create mode 100644 kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java diff --git a/egovframe-template-simple-react-contribution/src/css/component.css b/egovframe-template-simple-react-contribution/src/css/component.css index 058c969..af823cc 100644 --- a/egovframe-template-simple-react-contribution/src/css/component.css +++ b/egovframe-template-simple-react-contribution/src/css/component.css @@ -32,9 +32,11 @@ /* Board */ .board_list {border-top: 2px solid #222;} .board_list .head {display: table; table-layout: fixed; width: 100%;} -.board_list .head > span {display: table-cell; padding: 25px 0 27px 0; border-bottom: 1px solid #888; font-size: 16px; font-weight: 500px; text-align: center;} +/* changed by lim padding: 25px 0 27px 0; */ +.board_list .head > span {display: table-cell; padding: 10px 0 10px 0; border-bottom: 1px solid #888; font-size: 16px; font-weight: 500px; text-align: center;} .board_list .result .list_item {display: table; width: 100%; table-layout: fixed;} -.board_list .result .list_item > div {display: table-cell; padding: 18px 0 20px 0; border-bottom: 1px solid #dde2e5; color: #666; font-size: 16px; text-align: center; vertical-align: middle;} +/* changed by lim padding: 18px 0 20px 0; */ +.board_list .result .list_item > div {display: table-cell; padding: 7px 0 7px 0; border-bottom: 1px solid #dde2e5; color: #666; font-size: 16px; text-align: center; vertical-align: middle;} .board_list .result .list_item > div.al {padding: 18px 30px 20px 30px; text-align: left;} .board_list .result .list_item > div.reply {position: relative; padding: 18px 30px 20px 52px;} .board_list .result .list_item > div.reply::before {content: ""; display: block; position: absolute; left: 27px; top: 24px; width: 22px; height: 14px; background: url(css/images/ico_reply.png) no-repeat;} @@ -245,7 +247,7 @@ select::-ms-expand {display:none;} /* Title */ -.tit_1 {position: relative; padding-bottom: 50px; color: #222; font-size: 48px; font-weight: 500; letter-spacing: -2px; line-height: 48px;} +.tit_1 {position: relative; padding-bottom: 20px; color: #222; font-size: 38px; font-weight: 500; letter-spacing: -2px; line-height: 48px;} /* changed by lim padding-bottom: 50px; font-size: 48px;*/ .tit_1::after {content: ""; display: block; position: absolute; left: 0; bottom: 0; width: 30px; height: 2px; background: #0465be;} .tit_2 {font-size: 30px; font-weight: 700;} 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 cad6625..d3a9a6b 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 @@ -1,13 +1,147 @@ -import React from 'react'; +import React, { useState, useEffect, useCallback, useRef } from 'react'; +import { Link, useLocation } from 'react-router-dom'; +import * as EgovNet from 'api/egovFetch'; +import URL from 'constants/url'; -function UserConnections(props) { +import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; +import EgovPaging from 'components/EgovPaging'; + +import { itemIdxByPage } from 'utils/calc'; + +function PrivacyConnections(props) { + // console.group("EgovAdminPrivacyList"); + // console.log("[Start] EgovAdminPrivacyList ------------------------------"); + // console.log("EgovAdminPrivacyList [props] : ", props); + + const location = useLocation(); + // console.log("EgovAdminPrivacyList [location] : ", location); + + // const cndRef = useRef(); + // const wrdRef = useRef(); + + // eslint-disable-next-line no-unused-vars + const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });// 기존 조회에서 접근 했을 시 || 신규로 접근 했을 시 + const [paginationInfo, setPaginationInfo] = useState({}); + + const [listTag, setListTag] = useState([]); + + const retrieveList = useCallback((srchCnd) => { + // console.groupCollapsed("EgovAdminUsageList.retrieveList()"); + + const retrieveListURL = '/admin/logs/privacy'; + + const requestOptions = { + method: "POST", + headers: { + 'Content-type': 'application/json', + }, + body: JSON.stringify(srchCnd) + } + + EgovNet.requestFetch(retrieveListURL, + requestOptions, + (resp) => { + setPaginationInfo(resp.result.paginationInfo); + + let mutListTag = []; + listTag.push(

데이터가 없습니다.

); // 게시판 목록 초기값 + + const resultCnt = parseInt(resp.result.resultCnt); + const currentPageNo = resp.result.paginationInfo.currentPageNo; + const pageSize = resp.result.paginationInfo.pageSize; + + const startIndex = (currentPageNo - 1) * pageSize; + const endIndex = Math.min(startIndex + pageSize, resultCnt); + + // 리스트 항목 구성 + for (let index = startIndex; index < endIndex; index++) { + const listIdx = itemIdxByPage(resultCnt, currentPageNo, 0, index); // pageSize 로 넣으면 listIdx값이 2배씩 줄어서 0으로 수정 + const item = resp.result.resultList[index]; + + mutListTag.push( +
+
{listIdx}
+
{item.userId}
+
{item.targetUserId}
+
{item.accessType === "PRV_LIST" ? "사용자현황 조회" : item.accessType === "PRV_VIEW" ? "User 상세조회" : "User 수정"}
+
{item.ipAddress}
+
{item.accessDt}
+
+ ); + } + setListTag(mutListTag); + }, + function (resp) { + console.log("err response : ", resp); + } + ); + // console.groupEnd("EgovAdminPrivacyList.retrieveList()"); + },[listTag]); + + useEffect(() => { + retrieveList(searchCondition); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // console.log("------------------------------EgovAdminPrivacyList [End]"); + // console.groupEnd("EgovAdminPrivacyList"); return (
- UserConnections +
+ {/* */} +
+
    +
  • Home
  • +
  • 사이트관리
  • +
  • 로그현황
  • +
+
+ {/* */} + +
+ {/* */} + + {/* */} + +
+ {/* */} + +
+

개인정보 로그현황

+
+ + {/* */} +
+
+ 번호 + 관리자 ID + 수정 ID + 타입 + 접속IP + 변경일자 +
+
+ {listTag} +
+
+ {/* */} + +
+ {/* */} + { + retrieveList({ ...searchCondition, pageIndex: passedPage }) //, searchCnd: cndRef.current.value, searchWrd: wrdRef.current.value + }} /> + {/* */} +
+ + {/* */} +
+
+
); } -export default UserConnections; \ No newline at end of file +export default PrivacyConnections; \ No newline at end of file diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java new file mode 100644 index 0000000..d30cd0f --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/AdminLogsController.java @@ -0,0 +1,79 @@ +package com.dbnt.kcscbackend.admin.logs; + +import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog; +import com.dbnt.kcscbackend.admin.logs.service.AdminLogsService; +import com.dbnt.kcscbackend.auth.entity.LoginVO; +import com.dbnt.kcscbackend.config.common.BaseController; +import com.dbnt.kcscbackend.config.common.ResponseCode; +import com.dbnt.kcscbackend.config.common.ResultVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.egovframe.rte.fdl.property.EgovPropertyService; +import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin/logs") +@Tag(name="AdminLogsController", description = "사이트관리 로그현황 메뉴 컨트롤러") +public class AdminLogsController extends BaseController { + + @Resource(name = "propertiesService") + protected EgovPropertyService propertyService; + + private final AdminLogsService adminLogsService; + + @Operation( + summary = "로그현황 - 개인정보 로그", + description = "개인정보 로그현황", + tags = {"AdminLogsController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님") + }) + @RequestMapping(method = RequestMethod.POST, value = "/privacy", consumes = MediaType.APPLICATION_JSON_VALUE) + public ResultVO selectPrivacyLogsList(@RequestBody ThPrivacyLog thPrivacyLog, @AuthenticationPrincipal LoginVO user) + throws Exception { + + ResultVO resultVO = new ResultVO(); + Map resultMap = adminLogsService.selectPrivacyList(); + + PaginationInfo paginationInfo = new PaginationInfo(); + + paginationInfo.setCurrentPageNo(thPrivacyLog.getPageIndex()); + paginationInfo.setRecordCountPerPage(propertyService.getInt("Globals.pageUnit")); + paginationInfo.setPageSize(propertyService.getInt("Globals.pageSize")); + + thPrivacyLog.setFirstIndex(paginationInfo.getFirstRecordIndex()); + thPrivacyLog.setLastIndex(paginationInfo.getLastRecordIndex()); + thPrivacyLog.setRecordCountPerPage(paginationInfo.getRecordCountPerPage()); + + int totCnt = Integer.parseInt((String)resultMap.get("resultCnt")); + paginationInfo.setTotalRecordCount(totCnt); + +// resultMap.put("resultList", adminLogsService.selectPrivacyList()); +// resultMap.put("resultList", resultMap.get("resultList")); +// resultMap.put("resultCnt", totCnt); + resultMap.put("paginationInfo", paginationInfo); + + resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); + resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage()); + resultVO.setResult(resultMap); + return resultVO; + } + + +} 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 new file mode 100644 index 0000000..ee29534 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/entity/ThPrivacyLog.java @@ -0,0 +1,99 @@ +package com.dbnt.kcscbackend.admin.logs.entity; + +import java.io.Serializable; +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 +@Setter +@Accessors(chain = true) +@Entity +@NoArgsConstructor +@DynamicInsert +@DynamicUpdate +@Table(name = "th_user_privacy_log") +public class ThPrivacyLog implements Serializable { + private static final long serialVersionUID = -3779821913760046011L; + + @Transient + @Schema(description = "검색시작일") + private String searchBgnDe = ""; + + @Transient + @Schema(description = "검색조건") + private String searchCnd = ""; + + @Transient + @Schema(description = "검색종료일") + private String searchEndDe = ""; + + @Transient + @Schema(description = "검색단어") + private String searchWrd = ""; + + @Transient + @Schema(description = "정렬순서(DESC,ASC)") + private long sortOrdr = 0L; + + @Transient + @Schema(description = "검색사용여부") + private String searchUseYn = ""; + + @Transient + @Schema(description = "현재페이지") + private int pageIndex = 1; + + @Transient + @Schema(description = "페이지갯수") + private int pageUnit = 10; + + @Transient + @Schema(description = "페이지사이즈") + private int pageSize = 10; + + @Transient + @Schema(description = "첫페이지 인덱스") + private int firstIndex = 1; + + @Transient + @Schema(description = "마지막페이지 인덱스") + private int lastIndex = 1; + + @Transient + @Schema(description = "페이지당 레코드 개수") + private int recordCountPerPage = 10; + + @Transient + @Schema(description = "레코드 번호") + private int rowNo = 0; + + @Id + @Column(name = "upl_seq") + private Long uplSeq; + + @Column(name = "user_id") + private String userId; + + @Column(name = "target_user_id") + private String targetUserId; + + @Column(name = "access_type") + private String accessType; + + @Column(name = "ip_address") + private String ipAddress; + + @Column(name = "access_dt") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate accessDt; +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/mapper/AdminLogsMapper.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/mapper/AdminLogsMapper.java new file mode 100644 index 0000000..03f8926 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/mapper/AdminLogsMapper.java @@ -0,0 +1,7 @@ +package com.dbnt.kcscbackend.admin.logs.mapper; + +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AdminLogsMapper { +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/PrivacyLogsRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/PrivacyLogsRepository.java new file mode 100644 index 0000000..aca2cb7 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/repository/PrivacyLogsRepository.java @@ -0,0 +1,12 @@ +package com.dbnt.kcscbackend.admin.logs.repository; + +import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface PrivacyLogsRepository extends JpaRepository { + long count(); // 전체 레코드 수를 반환하는 메서드 + + List findAllByOrderByUplSeqDesc(); +} 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 new file mode 100644 index 0000000..11ad845 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/logs/service/AdminLogsService.java @@ -0,0 +1,39 @@ +package com.dbnt.kcscbackend.admin.logs.service; + +import com.dbnt.kcscbackend.admin.logs.entity.ThPrivacyLog; +import com.dbnt.kcscbackend.admin.logs.repository.PrivacyLogsRepository; +import lombok.RequiredArgsConstructor; +import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@RequiredArgsConstructor +public class AdminLogsService extends EgovAbstractServiceImpl { + + private final PrivacyLogsRepository privacyLogsRepository; + +// public List selectPrivacyList(){ +// return privacyLogsRepository.findAll(); +// } + public Map selectPrivacyList() { + Map resultMap = new HashMap<>(); + + // 전체 레코드 수 가져오기 + long totalRecordCount = privacyLogsRepository.count(); + + // 개수를 resultMap에 추가 + resultMap.put("resultCnt", String.valueOf(totalRecordCount)); + + // 개인 정보 로그 리스트 가져오기 + List privacyLogList = privacyLogsRepository.findAllByOrderByUplSeqDesc(); + + // 결과를 resultMap에 추가 + resultMap.put("resultList", privacyLogList); + + return resultMap; + } +}