만료 토큰 재발급 절차 수정.

기준코드 검색 페이지 즐겨찾기 기능 추가.
thkim
강석 최 2024-02-02 16:50:54 +09:00
parent cdd6f726c2
commit 64e4b07953
12 changed files with 218 additions and 67 deletions

View File

@ -29,7 +29,11 @@ export function requestFetch(url, requestOptions, handler, errorHandler) {
const accessToken = getLocalItem('accessToken'); const accessToken = getLocalItem('accessToken');
const sessionUser = parseJwt(accessToken); const sessionUser = parseJwt(accessToken);
const sessionUserId = sessionUser?.id || null; const sessionUserId = sessionUser?.id || null;
const refreshToken = getLocalItem('refreshToken');
if(accessToken && new Date(sessionUser.exp*1000) < new Date()){
//만료된 토큰 재발급 절차 진행.
accessTokenRefresh(url, requestOptions, handler, errorHandler);
}else{
if(sessionUserId != null){ if(sessionUserId != null){
if( !requestOptions['headers'] ) requestOptions['headers']={} if( !requestOptions['headers'] ) requestOptions['headers']={}
if( !requestOptions['headers']['Authorization'] ) requestOptions['headers']['Authorization']=null; if( !requestOptions['headers']['Authorization'] ) requestOptions['headers']['Authorization']=null;
@ -48,15 +52,13 @@ export function requestFetch(url, requestOptions, handler, errorHandler) {
fetch(SERVER_URL + url, requestOptions) fetch(SERVER_URL + url, requestOptions)
.then(response => {// response Stream. Not completion object .then(response => {// response Stream. Not completion object
//console.log("requestFetch [Response Stream] ", response);
return response.json(); return response.json();
}) })
.then((resp) => { .then((resp) => {
if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) { if (Number(resp.resultCode) === Number(CODE.RCV_ERROR_AUTH)) {
//accessToken 갱신 요청 alert("로그인이 해제되었습니다.")
accessTokenRefresh(url, requestOptions, handler, errorHandler); window.location.href = "/login"
return resp; }else{
} else {
return resp; return resp;
} }
}) })
@ -87,7 +89,7 @@ export function requestFetch(url, requestOptions, handler, errorHandler) {
console.log("requestFetch finally end"); console.log("requestFetch finally end");
console.groupEnd("requestFetch"); console.groupEnd("requestFetch");
}); });
}
} }
function accessTokenRefresh(url, requestOptions, handler, errorHandler){ function accessTokenRefresh(url, requestOptions, handler, errorHandler){

View File

@ -0,0 +1,46 @@
import React, {useState} from "react";
import {AiFillStar} from "react-icons/ai";
import {getLocalItem} from "utils/storage";
import * as EgovNet from "../../../api/egovFetch";
function FavoriteIcon({item}){
const [favoriteChk, setFavoriteChk] = useState(item.favoriteChk);
function favoriteStateChange(groupSeq, checked){
EgovNet.requestFetch(
'/standardCode/document-favorite',
{
method: "POST",
headers: {
'Content-type': 'application/json',
},
body:JSON.stringify({groupSeq: groupSeq, active: checked})
},
(resp) => {
},
function (resp) {
console.log("err response : ", resp);
}
);
}
return (
<div className="star clickable"
onClick={()=>{
const accessToken = getLocalItem('accessToken')
if(accessToken) {
favoriteStateChange(item.groupSeq, !favoriteChk)
setFavoriteChk(!favoriteChk)
}else{
alert("로그인 후 이용 가능한 서비스 입니다.")
}
}}>
<AiFillStar color={favoriteChk?'#FFC000':''}/>
</div>
);
}
export default FavoriteIcon;

View File

@ -1,8 +1,7 @@
import React from 'react'; import React from 'react';
import {AiFillStar} from "react-icons/ai";
import Col from "react-bootstrap/Col"; import Col from "react-bootstrap/Col";
import Row from "react-bootstrap/Row"; import Row from "react-bootstrap/Row";
import FavoriteIcon from "./FavoriteIcon";
function StandardCodeList({listData, filterData}) { function StandardCodeList({listData, filterData}) {
@ -76,7 +75,7 @@ function StandardCodeList({listData, filterData}) {
})} })}
</Row> </Row>
</div> </div>
<div className="star clickable"><AiFillStar/></div> <FavoriteIcon item={item}/>
</div> </div>
) )
})} })}

View File

@ -35,6 +35,9 @@ public class LoginVO implements Serializable{
*/ */
private static final long serialVersionUID = -8274004534207618049L; private static final long serialVersionUID = -8274004534207618049L;
@Schema(description = "사용자 번호")
private Integer userSeq;
@Schema(description = "아이디") @Schema(description = "아이디")
@Pattern(regexp = "^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$") @Pattern(regexp = "^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$")
@NotBlank(message = "아이디를 입력해주세요.") @NotBlank(message = "아이디를 입력해주세요.")

View File

@ -67,6 +67,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
LoginVO loginVO = new LoginVO(); LoginVO loginVO = new LoginVO();
if( verificationFlag ){ if( verificationFlag ){
logger.debug("jwtToken validated"); logger.debug("jwtToken validated");
loginVO.setUserSeq(Integer.parseInt(jwtTokenUtil.getUserSeqFromToken(jwtToken)));
loginVO.setId(id); loginVO.setId(id);
loginVO.setUserSe( jwtTokenUtil.getUserSeFromToken(jwtToken) ); loginVO.setUserSe( jwtTokenUtil.getUserSeFromToken(jwtToken) );
// loginVO.setUniqId( jwtTokenUtil.getInfoFromToken("uniqId",jwtToken) ); // loginVO.setUniqId( jwtTokenUtil.getInfoFromToken("uniqId",jwtToken) );

View File

@ -6,6 +6,7 @@ import com.dbnt.kcscbackend.config.common.ResponseCode;
import com.dbnt.kcscbackend.config.common.ResultVO; import com.dbnt.kcscbackend.config.common.ResultVO;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentCodeList; import com.dbnt.kcscbackend.standardCode.entity.TnDocumentCodeList;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentContent; import com.dbnt.kcscbackend.standardCode.entity.TnDocumentContent;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentFavorites;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentInfo; import com.dbnt.kcscbackend.standardCode.entity.TnDocumentInfo;
import com.dbnt.kcscbackend.standardCode.service.StandardCodeService; import com.dbnt.kcscbackend.standardCode.service.StandardCodeService;
import com.dbnt.kcscbackend.standardCode.service.StandardCodeVO; import com.dbnt.kcscbackend.standardCode.service.StandardCodeVO;
@ -152,9 +153,9 @@ public class StandardCodeController extends BaseController {
Map<String, Object> resultMap = new HashMap<>(); Map<String, Object> resultMap = new HashMap<>();
tnDocumentInfo.makeListCode(); tnDocumentInfo.makeListCode();
tnDocumentInfo.setUserSeq(user.getUserSeq());
resultMap.put("resultList", standardCodeService.selectStandardCodeList(tnDocumentInfo)); resultMap.put("resultList", standardCodeService.selectStandardCodeList(tnDocumentInfo));
resultMap.put("resultCnt", standardCodeService.selectStandardCodeListCnt(tnDocumentInfo)); resultMap.put("resultCnt", standardCodeService.selectStandardCodeListCnt(tnDocumentInfo));
resultMap.put("user", user);
resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage()); resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
@ -184,6 +185,34 @@ public class StandardCodeController extends BaseController {
return resultVO; return resultVO;
} }
@Operation(
summary = "건설기준코드 즐겨찾기 추가, 삭제",
description = "건설기준코드 즐겨찾기 추가, 삭제",
tags = {"StandardCodeController"}
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "403", description = "인가된 사용자가 아님")
})
@PostMapping(value = "/document-favorite")
public ResultVO setDocumentFavorite(@RequestBody TnDocumentFavorites favorites, @AuthenticationPrincipal LoginVO loginUser) throws Exception {
ResultVO resultVO = new ResultVO();
if(favorites.getActive()==null){
resultVO.setResultCode(ResponseCode.SAVE_ERROR.getCode());
resultVO.setResultMessage(ResponseCode.SAVE_ERROR.getMessage());
return resultVO;
}
if(favorites.getActive()){
standardCodeService.saveFavorites(loginUser.getUserSeq(), favorites.getGroupSeq());
}else{
standardCodeService.deleteFavorites(loginUser.getUserSeq(), favorites.getGroupSeq());
}
resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());
return resultVO;
}
@Operation( @Operation(
summary = "건설기준코드 개정이력 조회", summary = "건설기준코드 개정이력 조회",
description = "건설기준코드 개정이력 조회", description = "건설기준코드 개정이력 조회",

View File

@ -45,6 +45,8 @@ public class TnDocumentCodeList {
@Transient @Transient
private Integer remarkCnt; private Integer remarkCnt;
@Transient @Transient
private Boolean favoriteChk;
@Transient
private List<TnDocumentInfo> historyList; private List<TnDocumentInfo> historyList;
} }

View File

@ -0,0 +1,40 @@
package com.dbnt.kcscbackend.standardCode.entity;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Table(name = "tn_document_favorites")
@IdClass(TnDocumentFavorites.TnDocumentFavoritesId.class)
public class TnDocumentFavorites {
@Id
@Column(name = "user_seq")
private Integer userSeq;
@Id
@Column(name = "group_seq")
private Integer groupSeq;
@Transient
private Boolean active;
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class TnDocumentFavoritesId implements Serializable {
private Integer userSeq;
private Integer groupSeq;
}
}

View File

@ -100,6 +100,8 @@ public class TnDocumentInfo {
private String category2 = ""; private String category2 = "";
@Transient @Transient
private String category3 = ""; private String category3 = "";
@Transient
private Integer userSeq;
@JsonIgnore @JsonIgnore
public void makeListCode(){ public void makeListCode(){

View File

@ -0,0 +1,8 @@
package com.dbnt.kcscbackend.standardCode.repository;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentFavorites;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TnDocumentFavoritesRepository extends JpaRepository<TnDocumentFavorites, TnDocumentFavorites.TnDocumentFavoritesId> {
}

View File

@ -1,11 +1,9 @@
package com.dbnt.kcscbackend.standardCode.service; package com.dbnt.kcscbackend.standardCode.service;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentCodeList; import com.dbnt.kcscbackend.standardCode.entity.*;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentContent;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentGroup;
import com.dbnt.kcscbackend.standardCode.entity.TnDocumentInfo;
import com.dbnt.kcscbackend.standardCode.mapper.StandardCodeMapper; import com.dbnt.kcscbackend.standardCode.mapper.StandardCodeMapper;
import com.dbnt.kcscbackend.standardCode.repository.TnDocumentContentRepository; import com.dbnt.kcscbackend.standardCode.repository.TnDocumentContentRepository;
import com.dbnt.kcscbackend.standardCode.repository.TnDocumentFavoritesRepository;
import com.dbnt.kcscbackend.standardCode.repository.TnDocumentGroupRepository; import com.dbnt.kcscbackend.standardCode.repository.TnDocumentGroupRepository;
import com.dbnt.kcscbackend.standardCode.repository.TnDocumentInfoRepository; import com.dbnt.kcscbackend.standardCode.repository.TnDocumentInfoRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -23,6 +21,7 @@ public class StandardCodeService extends EgovAbstractServiceImpl {
private final TnDocumentGroupRepository tnDocumentGroupRepository; private final TnDocumentGroupRepository tnDocumentGroupRepository;
private final TnDocumentContentRepository tnDocumentContentRepository; private final TnDocumentContentRepository tnDocumentContentRepository;
private final TnDocumentInfoRepository tnDocumentInfoRepository; private final TnDocumentInfoRepository tnDocumentInfoRepository;
private final TnDocumentFavoritesRepository favoritesRepository;
private final StandardCodeMapper standardCodeMapper; private final StandardCodeMapper standardCodeMapper;
@Transactional @Transactional
@ -74,4 +73,15 @@ public class StandardCodeService extends EgovAbstractServiceImpl {
public List<TnDocumentGroup> selectTnDocumentGroupToGroupFullCdLike(String groupFullCd) { public List<TnDocumentGroup> selectTnDocumentGroupToGroupFullCdLike(String groupFullCd) {
return tnDocumentGroupRepository.findByGroupFullCdLike(groupFullCd+"__"); return tnDocumentGroupRepository.findByGroupFullCdLike(groupFullCd+"__");
} }
public void saveFavorites(Integer userSeq, Integer groupSeq){
TnDocumentFavorites favorites = new TnDocumentFavorites();
favorites.setUserSeq(userSeq);
favorites.setGroupSeq(groupSeq);
favoritesRepository.save(favorites);
}
public void deleteFavorites(Integer userSeq, Integer groupSeq){
favoritesRepository.deleteById(new TnDocumentFavorites.TnDocumentFavoritesId(userSeq, groupSeq));
}
} }

View File

@ -35,11 +35,20 @@
c.rvsn_remark , c.rvsn_remark ,
c.kcsc_cd, c.kcsc_cd,
tdi.doc_file_grp_id, tdi.doc_file_grp_id,
c.group_seq c.group_seq,
tdf.user_seq is not null as favoriteChk
from tn_document_group a from tn_document_group a
inner join tn_document_group b on a.group_seq = b.parent_group_seq inner join tn_document_group b on a.group_seq = b.parent_group_seq
inner join tn_document_group c on b.group_seq = c.parent_group_seq inner join tn_document_group c on b.group_seq = c.parent_group_seq
left join tn_document_info tdi on c.group_seq = tdi.group_seq left join tn_document_info tdi on c.group_seq = tdi.group_seq
left join tn_document_favorites tdf
on c.group_seq = tdf.group_seq
<if test='userSeq == null'>
and 1=0
</if>
<if test='userSeq != null'>
and tdf.user_seq = #{userSeq}
</if>
<include refid="selectStandardCodeListWhere"></include> <include refid="selectStandardCodeListWhere"></include>
order by c.kcsc_cd order by c.kcsc_cd
</select> </select>