test api 추가, 개발서버 토큰 만료시간 조정
This commit is contained in:
@@ -54,59 +54,59 @@ public class AuthController {
|
|||||||
@Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.")
|
@Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "로그인 성공",
|
description = "로그인 성공",
|
||||||
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "401",
|
responseCode = "401",
|
||||||
description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)",
|
description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
schema = @Schema(implementation = ErrorResponse.class),
|
schema = @Schema(implementation = ErrorResponse.class),
|
||||||
examples = {
|
examples = {
|
||||||
@ExampleObject(
|
@ExampleObject(
|
||||||
name = "아이디 입력 오류",
|
name = "아이디 입력 오류",
|
||||||
description = "존재하지 않는 아이디",
|
description = "존재하지 않는 아이디",
|
||||||
value =
|
value =
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
"code": "LOGIN_ID_NOT_FOUND",
|
"code": "LOGIN_ID_NOT_FOUND",
|
||||||
"message": "아이디를 잘못 입력하셨습니다."
|
"message": "아이디를 잘못 입력하셨습니다."
|
||||||
}
|
}
|
||||||
"""),
|
"""),
|
||||||
@ExampleObject(
|
@ExampleObject(
|
||||||
name = "비밀번호 입력 오류 (4회 이하)",
|
name = "비밀번호 입력 오류 (4회 이하)",
|
||||||
description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우",
|
description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우",
|
||||||
value =
|
value =
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
"code": "LOGIN_PASSWORD_MISMATCH",
|
"code": "LOGIN_PASSWORD_MISMATCH",
|
||||||
"message": "비밀번호를 잘못 입력하셨습니다."
|
"message": "비밀번호를 잘못 입력하셨습니다."
|
||||||
}
|
}
|
||||||
"""),
|
"""),
|
||||||
@ExampleObject(
|
@ExampleObject(
|
||||||
name = "비밀번호 오류 횟수 초과",
|
name = "비밀번호 오류 횟수 초과",
|
||||||
description = "비밀번호 5회 이상 오류로 계정 잠김",
|
description = "비밀번호 5회 이상 오류로 계정 잠김",
|
||||||
value =
|
value =
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
"code": "LOGIN_PASSWORD_EXCEEDED",
|
"code": "LOGIN_PASSWORD_EXCEEDED",
|
||||||
"message": "비밀번호 오류 횟수를 초과하여 이용하실 수 없습니다. 로그인 오류에 대해 관리자에게 문의하시기 바랍니다."
|
"message": "비밀번호 오류 횟수를 초과하여 이용하실 수 없습니다. 로그인 오류에 대해 관리자에게 문의하시기 바랍니다."
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
public ApiResponseDto<TokenResponse> signin(
|
public ApiResponseDto<TokenResponse> signin(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "로그인 요청 정보",
|
description = "로그인 요청 정보",
|
||||||
required = true)
|
required = true)
|
||||||
@RequestBody
|
@RequestBody
|
||||||
SignInRequest request,
|
SignInRequest request,
|
||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
|
|
||||||
Authentication authentication =
|
Authentication authentication =
|
||||||
authenticationManager.authenticate(
|
authenticationManager.authenticate(
|
||||||
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
|
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
|
||||||
|
|
||||||
String status = authService.getUserStatus(request);
|
String status = authService.getUserStatus(request);
|
||||||
|
|
||||||
@@ -124,17 +124,17 @@ public class AuthController {
|
|||||||
|
|
||||||
// Redis에 RefreshToken 저장 (TTL = 7일)
|
// Redis에 RefreshToken 저장 (TTL = 7일)
|
||||||
refreshTokenService.save(
|
refreshTokenService.save(
|
||||||
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
||||||
|
|
||||||
// HttpOnly + Secure 쿠키에 RefreshToken 저장
|
// HttpOnly + Secure 쿠키에 RefreshToken 저장
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, refreshToken)
|
ResponseCookie.from(refreshCookieName, refreshToken)
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure)
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
@@ -153,20 +153,19 @@ public class AuthController {
|
|||||||
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
|
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "재발급 성공",
|
description = "재발급 성공",
|
||||||
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "401",
|
responseCode = "403",
|
||||||
description = "만료되었거나 유효하지 않은 리프레시 토큰",
|
description = "만료되었거나 유효하지 않은 리프레시 토큰",
|
||||||
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
})
|
})
|
||||||
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response)
|
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response)
|
||||||
throws AccessDeniedException {
|
throws AccessDeniedException {
|
||||||
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
|
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
|
||||||
throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
|
throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = jwtTokenProvider.getSubject(refreshToken);
|
String username = jwtTokenProvider.getSubject(refreshToken);
|
||||||
|
|
||||||
// Redis에 저장된 RefreshToken과 일치하는지 확인
|
// Redis에 저장된 RefreshToken과 일치하는지 확인
|
||||||
@@ -180,17 +179,17 @@ public class AuthController {
|
|||||||
|
|
||||||
// Redis 갱신
|
// Redis 갱신
|
||||||
refreshTokenService.save(
|
refreshTokenService.save(
|
||||||
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
||||||
|
|
||||||
// 쿠키 갱신
|
// 쿠키 갱신
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, newRefreshToken)
|
ResponseCookie.from(refreshCookieName, newRefreshToken)
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure)
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
MembersDto.Member member = new MembersDto.Member();
|
MembersDto.Member member = new MembersDto.Member();
|
||||||
@@ -201,12 +200,12 @@ public class AuthController {
|
|||||||
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.")
|
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "로그아웃 성공",
|
description = "로그아웃 성공",
|
||||||
content = @Content(schema = @Schema(implementation = Void.class)))
|
content = @Content(schema = @Schema(implementation = Void.class)))
|
||||||
})
|
})
|
||||||
public ApiResponseDto<ResponseEntity<Object>> logout(
|
public ApiResponseDto<ResponseEntity<Object>> logout(
|
||||||
Authentication authentication, HttpServletResponse response) {
|
Authentication authentication, HttpServletResponse response) {
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
String username = authentication.getName();
|
String username = authentication.getName();
|
||||||
// Redis에서 RefreshToken 삭제
|
// Redis에서 RefreshToken 삭제
|
||||||
@@ -215,13 +214,13 @@ public class AuthController {
|
|||||||
|
|
||||||
// 쿠키 삭제 (Max-Age=0)
|
// 쿠키 삭제 (Max-Age=0)
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, "")
|
ResponseCookie.from(refreshCookieName, "")
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure)
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(0)
|
.maxAge(0)
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
return ApiResponseDto.createOK(ResponseEntity.noContent().build());
|
return ApiResponseDto.createOK(ResponseEntity.noContent().build());
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity;
|
private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity;
|
||||||
private final QMapSheetAnalEntity mapSheetAnalEntity = QMapSheetAnalEntity.mapSheetAnalEntity;
|
private final QMapSheetAnalEntity mapSheetAnalEntity = QMapSheetAnalEntity.mapSheetAnalEntity;
|
||||||
private final QMapSheetAnalDataEntity mapSheetAnalDataEntity =
|
private final QMapSheetAnalDataEntity mapSheetAnalDataEntity =
|
||||||
QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
|
||||||
private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeomEntity =
|
private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeomEntity =
|
||||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||||
private final QMapSheetAnalSttcEntity mapSheetAnalSttcEntity =
|
private final QMapSheetAnalSttcEntity mapSheetAnalSttcEntity =
|
||||||
QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity;
|
QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 분석결과 목록 조회
|
* 분석결과 목록 조회
|
||||||
@@ -54,7 +54,7 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Page<InferenceResultDto.AnalResList> getInferenceResultList(
|
public Page<InferenceResultDto.AnalResList> getInferenceResultList(
|
||||||
InferenceResultDto.SearchReq searchReq) {
|
InferenceResultDto.SearchReq searchReq) {
|
||||||
Pageable pageable = searchReq.toPageable();
|
Pageable pageable = searchReq.toPageable();
|
||||||
// "0000" 전체조회
|
// "0000" 전체조회
|
||||||
BooleanBuilder builder = new BooleanBuilder();
|
BooleanBuilder builder = new BooleanBuilder();
|
||||||
@@ -68,35 +68,35 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<InferenceResultDto.AnalResList> content =
|
List<InferenceResultDto.AnalResList> content =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(
|
.select(
|
||||||
Projections.constructor(
|
Projections.constructor(
|
||||||
InferenceResultDto.AnalResList.class,
|
InferenceResultDto.AnalResList.class,
|
||||||
mapSheetAnalEntity.id,
|
mapSheetAnalEntity.id,
|
||||||
mapSheetAnalEntity.analTitle,
|
mapSheetAnalEntity.analTitle,
|
||||||
mapSheetAnalEntity.analMapSheet,
|
mapSheetAnalEntity.analMapSheet,
|
||||||
mapSheetAnalEntity.detectingCnt,
|
mapSheetAnalEntity.detectingCnt,
|
||||||
mapSheetAnalEntity.analStrtDttm,
|
mapSheetAnalEntity.analStrtDttm,
|
||||||
mapSheetAnalEntity.analEndDttm,
|
mapSheetAnalEntity.analEndDttm,
|
||||||
mapSheetAnalEntity.analSec,
|
mapSheetAnalEntity.analSec,
|
||||||
mapSheetAnalEntity.analPredSec,
|
mapSheetAnalEntity.analPredSec,
|
||||||
mapSheetAnalEntity.analState,
|
mapSheetAnalEntity.analState,
|
||||||
Expressions.stringTemplate(
|
Expressions.stringTemplate(
|
||||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState),
|
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState),
|
||||||
mapSheetAnalEntity.gukyuinUsed))
|
mapSheetAnalEntity.gukyuinUsed))
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.where(builder)
|
.where(builder)
|
||||||
.offset(pageable.getOffset())
|
.offset(pageable.getOffset())
|
||||||
.limit(pageable.getPageSize())
|
.limit(pageable.getPageSize())
|
||||||
.orderBy(mapSheetAnalEntity.id.desc())
|
.orderBy(mapSheetAnalEntity.id.desc())
|
||||||
.fetch();
|
.fetch();
|
||||||
|
|
||||||
long total =
|
long total =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(mapSheetAnalEntity.id)
|
.select(mapSheetAnalEntity.id)
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.where(builder)
|
.where(builder)
|
||||||
.fetchCount();
|
.fetchCount();
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
return new PageImpl<>(content, pageable, total);
|
||||||
}
|
}
|
||||||
@@ -112,40 +112,41 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
|
|
||||||
// 1. 최신 버전 UID를 가져오는 서브쿼리
|
// 1. 최신 버전 UID를 가져오는 서브쿼리
|
||||||
JPQLQuery<Long> latestVerUidSub =
|
JPQLQuery<Long> latestVerUidSub =
|
||||||
JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id));
|
JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id));
|
||||||
|
|
||||||
Optional<InferenceResultDto.AnalResSummary> content =
|
Optional<InferenceResultDto.AnalResSummary> content =
|
||||||
Optional.ofNullable(
|
Optional.ofNullable(
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(
|
.select(
|
||||||
Projections.constructor(
|
Projections.constructor(
|
||||||
InferenceResultDto.AnalResSummary.class,
|
InferenceResultDto.AnalResSummary.class,
|
||||||
mapSheetAnalEntity.id,
|
mapSheetAnalEntity.id,
|
||||||
mapSheetAnalEntity.analTitle,
|
mapSheetAnalEntity.analTitle,
|
||||||
tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"),
|
tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"),
|
||||||
mapSheetAnalEntity.targetYyyy,
|
mapSheetAnalEntity.targetYyyy,
|
||||||
mapSheetAnalEntity.compareYyyy,
|
mapSheetAnalEntity.compareYyyy,
|
||||||
mapSheetAnalEntity.analMapSheet,
|
mapSheetAnalEntity.analMapSheet,
|
||||||
mapSheetAnalEntity.analStrtDttm,
|
mapSheetAnalEntity.analStrtDttm,
|
||||||
mapSheetAnalEntity.analEndDttm,
|
mapSheetAnalEntity.analEndDttm,
|
||||||
mapSheetAnalEntity.analSec,
|
mapSheetAnalEntity.analSec,
|
||||||
mapSheetAnalEntity.analPredSec,
|
mapSheetAnalEntity.analPredSec,
|
||||||
mapSheetAnalEntity.resultUrl,
|
mapSheetAnalEntity.resultUrl,
|
||||||
mapSheetAnalEntity.detectingCnt,
|
mapSheetAnalEntity.detectingCnt,
|
||||||
mapSheetAnalEntity.accuracy,
|
mapSheetAnalEntity.accuracy,
|
||||||
mapSheetAnalEntity.analState,
|
mapSheetAnalEntity.analState,
|
||||||
Expressions.stringTemplate(
|
Expressions.stringTemplate(
|
||||||
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState)))
|
"fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState)))
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.leftJoin(tmm)
|
.leftJoin(tmm)
|
||||||
.on(mapSheetAnalEntity.modelUid.eq(tmm.id))
|
.on(mapSheetAnalEntity.modelUid.eq(tmm.id))
|
||||||
.leftJoin(tmv)
|
.leftJoin(tmv)
|
||||||
.on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub)))
|
.on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub)))
|
||||||
.where(mapSheetAnalEntity.id.eq(id))
|
.where(mapSheetAnalEntity.id.eq(id))
|
||||||
.fetchOne());
|
.fetchOne());
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 분석결과 상세 class name별 탐지 개수
|
* 분석결과 상세 class name별 탐지 개수
|
||||||
*
|
*
|
||||||
@@ -155,16 +156,16 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
@Override
|
@Override
|
||||||
public List<Dashboard> getDashboard(Long id) {
|
public List<Dashboard> getDashboard(Long id) {
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
Projections.constructor(
|
Projections.constructor(
|
||||||
Dashboard.class,
|
Dashboard.class,
|
||||||
mapSheetAnalSttcEntity.id.classAfterCd,
|
mapSheetAnalSttcEntity.id.classAfterCd,
|
||||||
mapSheetAnalSttcEntity.classAfterCnt.sum()))
|
mapSheetAnalSttcEntity.classAfterCnt.sum()))
|
||||||
.from(mapSheetAnalSttcEntity)
|
.from(mapSheetAnalSttcEntity)
|
||||||
.where(mapSheetAnalSttcEntity.id.analUid.eq(id))
|
.where(mapSheetAnalSttcEntity.id.analUid.eq(id))
|
||||||
.groupBy(mapSheetAnalSttcEntity.id.classAfterCd)
|
.groupBy(mapSheetAnalSttcEntity.id.classAfterCd)
|
||||||
.orderBy(mapSheetAnalSttcEntity.id.classAfterCd.asc())
|
.orderBy(mapSheetAnalSttcEntity.id.classAfterCd.asc())
|
||||||
.fetch();
|
.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -181,22 +182,22 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
public Page<MapSheetAnalDataGeomEntity> listInferenceResultWithGeom(
|
||||||
List<Long> ids, SearchGeoReq searchReq) {
|
List<Long> ids, SearchGeoReq searchReq) {
|
||||||
|
|
||||||
// 분석 차수
|
// 분석 차수
|
||||||
QMapSheetAnalDataGeomEntity detectedEntity =
|
QMapSheetAnalDataGeomEntity detectedEntity =
|
||||||
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
|
||||||
Pageable pageable = searchReq.toPageable();
|
Pageable pageable = searchReq.toPageable();
|
||||||
|
|
||||||
// 검색조건
|
// 검색조건
|
||||||
JPAQuery<MapSheetAnalDataGeomEntity> query =
|
JPAQuery<MapSheetAnalDataGeomEntity> query =
|
||||||
queryFactory
|
queryFactory
|
||||||
.selectFrom(detectedEntity)
|
.selectFrom(detectedEntity)
|
||||||
.where(
|
.where(
|
||||||
detectedEntity.dataUid.in(ids),
|
detectedEntity.dataUid.in(ids),
|
||||||
eqTargetClass(detectedEntity, searchReq.getTargetClass()),
|
eqTargetClass(detectedEntity, searchReq.getTargetClass()),
|
||||||
eqCompareClass(detectedEntity, searchReq.getCompareClass()),
|
eqCompareClass(detectedEntity, searchReq.getCompareClass()),
|
||||||
containsMapSheetNum(detectedEntity, searchReq.getMapSheetNum()));
|
containsMapSheetNum(detectedEntity, searchReq.getMapSheetNum()));
|
||||||
|
|
||||||
// count
|
// count
|
||||||
long total = query.fetchCount();
|
long total = query.fetchCount();
|
||||||
@@ -208,11 +209,11 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<MapSheetAnalDataGeomEntity> content =
|
List<MapSheetAnalDataGeomEntity> content =
|
||||||
query
|
query
|
||||||
.offset(pageable.getOffset())
|
.offset(pageable.getOffset())
|
||||||
.limit(pageable.getPageSize())
|
.limit(pageable.getPageSize())
|
||||||
.orderBy(orders.toArray(new OrderSpecifier[0]))
|
.orderBy(orders.toArray(new OrderSpecifier[0]))
|
||||||
.fetch();
|
.fetch();
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
return new PageImpl<>(content, pageable, total);
|
||||||
}
|
}
|
||||||
@@ -234,19 +235,19 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
// 기준년도 분류
|
// 기준년도 분류
|
||||||
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) {
|
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) {
|
||||||
builder.and(
|
builder.and(
|
||||||
mapSheetAnalDataGeomEntity
|
mapSheetAnalDataGeomEntity
|
||||||
.classAfterCd
|
.classAfterCd
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.eq(searchGeoReq.getTargetClass().toLowerCase()));
|
.eq(searchGeoReq.getTargetClass().toLowerCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 비교년도 분류
|
// 비교년도 분류
|
||||||
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) {
|
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) {
|
||||||
builder.and(
|
builder.and(
|
||||||
mapSheetAnalDataGeomEntity
|
mapSheetAnalDataGeomEntity
|
||||||
.classBeforeCd
|
.classBeforeCd
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.eq(searchGeoReq.getCompareClass().toLowerCase()));
|
.eq(searchGeoReq.getCompareClass().toLowerCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 분석도엽
|
// 분석도엽
|
||||||
@@ -256,39 +257,39 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<InferenceResultDto.Geom> content =
|
List<InferenceResultDto.Geom> content =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(
|
.select(
|
||||||
Projections.constructor(
|
Projections.constructor(
|
||||||
InferenceResultDto.Geom.class,
|
InferenceResultDto.Geom.class,
|
||||||
mapSheetAnalDataGeomEntity.compareYyyy,
|
mapSheetAnalDataGeomEntity.compareYyyy,
|
||||||
mapSheetAnalDataGeomEntity.targetYyyy,
|
mapSheetAnalDataGeomEntity.targetYyyy,
|
||||||
mapSheetAnalDataGeomEntity.classBeforeCd,
|
mapSheetAnalDataGeomEntity.classBeforeCd,
|
||||||
mapSheetAnalDataGeomEntity.classBeforeProb,
|
mapSheetAnalDataGeomEntity.classBeforeProb,
|
||||||
mapSheetAnalDataGeomEntity.classAfterCd,
|
mapSheetAnalDataGeomEntity.classAfterCd,
|
||||||
mapSheetAnalDataGeomEntity.classAfterProb,
|
mapSheetAnalDataGeomEntity.classAfterProb,
|
||||||
mapSheetAnalDataGeomEntity.mapSheetNum,
|
mapSheetAnalDataGeomEntity.mapSheetNum,
|
||||||
mapSheetAnalDataGeomEntity.geom,
|
mapSheetAnalDataGeomEntity.geom,
|
||||||
mapSheetAnalDataGeomEntity.geomCenter))
|
mapSheetAnalDataGeomEntity.geomCenter))
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.join(mapSheetAnalDataEntity)
|
.join(mapSheetAnalDataEntity)
|
||||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||||
.join(mapSheetAnalDataGeomEntity)
|
.join(mapSheetAnalDataGeomEntity)
|
||||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||||
.where(builder)
|
.where(builder)
|
||||||
.offset(pageable.getOffset())
|
.offset(pageable.getOffset())
|
||||||
.limit(pageable.getPageSize())
|
.limit(pageable.getPageSize())
|
||||||
.fetch();
|
.fetch();
|
||||||
|
|
||||||
long total =
|
long total =
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(mapSheetAnalDataGeomEntity.id)
|
.select(mapSheetAnalDataGeomEntity.id)
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.join(mapSheetAnalDataEntity)
|
.join(mapSheetAnalDataEntity)
|
||||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||||
.join(mapSheetAnalDataGeomEntity)
|
.join(mapSheetAnalDataGeomEntity)
|
||||||
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
|
||||||
.where(builder)
|
.where(builder)
|
||||||
.fetchCount();
|
.fetchCount();
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
return new PageImpl<>(content, pageable, total);
|
||||||
}
|
}
|
||||||
@@ -302,16 +303,18 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
@Override
|
@Override
|
||||||
public List<Long> getSheets(Long id) {
|
public List<Long> getSheets(Long id) {
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(mapSheetAnalDataEntity.mapSheetNum)
|
.select(mapSheetAnalDataEntity.mapSheetNum)
|
||||||
.from(mapSheetAnalEntity)
|
.from(mapSheetAnalEntity)
|
||||||
.join(mapSheetAnalDataEntity)
|
.join(mapSheetAnalDataEntity)
|
||||||
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
|
||||||
.where(mapSheetAnalEntity.id.eq(id))
|
.where(mapSheetAnalEntity.id.eq(id))
|
||||||
.groupBy(mapSheetAnalDataEntity.mapSheetNum)
|
.groupBy(mapSheetAnalDataEntity.mapSheetNum)
|
||||||
.fetch();
|
.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Pageable의 Sort를 QueryDSL OrderSpecifier로 변환 */
|
/**
|
||||||
|
* Pageable의 Sort를 QueryDSL OrderSpecifier로 변환
|
||||||
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
private List<OrderSpecifier<?>> getOrderSpecifiers(Sort sort) {
|
private List<OrderSpecifier<?>> getOrderSpecifiers(Sort sort) {
|
||||||
List<OrderSpecifier<?>> orders = new ArrayList<>();
|
List<OrderSpecifier<?>> orders = new ArrayList<>();
|
||||||
@@ -326,8 +329,7 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
// 유효한 필드만 처리
|
// 유효한 필드만 처리
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case "classBeforeCd" -> orders.add(new OrderSpecifier(direction, entity.classBeforeCd));
|
case "classBeforeCd" -> orders.add(new OrderSpecifier(direction, entity.classBeforeCd));
|
||||||
case "classBeforeProb" ->
|
case "classBeforeProb" -> orders.add(new OrderSpecifier(direction, entity.classBeforeProb));
|
||||||
orders.add(new OrderSpecifier(direction, entity.classBeforeProb));
|
|
||||||
case "classAfterCd" -> orders.add(new OrderSpecifier(direction, entity.classAfterCd));
|
case "classAfterCd" -> orders.add(new OrderSpecifier(direction, entity.classAfterCd));
|
||||||
case "classAfterProb" -> orders.add(new OrderSpecifier(direction, entity.classAfterProb));
|
case "classAfterProb" -> orders.add(new OrderSpecifier(direction, entity.classAfterProb));
|
||||||
case "mapSheetNum" -> orders.add(new OrderSpecifier(direction, entity.mapSheetNum));
|
case "mapSheetNum" -> orders.add(new OrderSpecifier(direction, entity.mapSheetNum));
|
||||||
@@ -336,8 +338,9 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
case "area" -> orders.add(new OrderSpecifier(direction, entity.area));
|
case "area" -> orders.add(new OrderSpecifier(direction, entity.area));
|
||||||
case "createdDttm" -> orders.add(new OrderSpecifier(direction, entity.createdDttm));
|
case "createdDttm" -> orders.add(new OrderSpecifier(direction, entity.createdDttm));
|
||||||
case "updatedDttm" -> orders.add(new OrderSpecifier(direction, entity.updatedDttm));
|
case "updatedDttm" -> orders.add(new OrderSpecifier(direction, entity.updatedDttm));
|
||||||
// 유효하지 않은 필드는 무시
|
// 유효하지 않은 필드는 무시
|
||||||
default -> {}
|
default -> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,21 +349,21 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BooleanExpression eqTargetClass(
|
private BooleanExpression eqTargetClass(
|
||||||
QMapSheetAnalDataGeomEntity detectedEntity, String targetClass) {
|
QMapSheetAnalDataGeomEntity detectedEntity, String targetClass) {
|
||||||
return targetClass != null && !targetClass.isEmpty()
|
return targetClass != null && !targetClass.isEmpty()
|
||||||
? detectedEntity.classAfterCd.toLowerCase().eq(targetClass.toLowerCase())
|
? detectedEntity.classAfterCd.toLowerCase().eq(targetClass.toLowerCase())
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BooleanExpression eqCompareClass(
|
private BooleanExpression eqCompareClass(
|
||||||
QMapSheetAnalDataGeomEntity detectedEntity, String compareClass) {
|
QMapSheetAnalDataGeomEntity detectedEntity, String compareClass) {
|
||||||
return compareClass != null && !compareClass.isEmpty()
|
return compareClass != null && !compareClass.isEmpty()
|
||||||
? detectedEntity.classBeforeCd.toLowerCase().eq(compareClass.toLowerCase())
|
? detectedEntity.classBeforeCd.toLowerCase().eq(compareClass.toLowerCase())
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BooleanExpression containsMapSheetNum(
|
private BooleanExpression containsMapSheetNum(
|
||||||
QMapSheetAnalDataGeomEntity detectedEntity, List<Long> mapSheet) {
|
QMapSheetAnalDataGeomEntity detectedEntity, List<Long> mapSheet) {
|
||||||
if (mapSheet == null || mapSheet.isEmpty()) {
|
if (mapSheet == null || mapSheet.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.kamco.cd.kamcoback.test;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
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.springframework.web.ErrorResponse;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "test api", description = "test api")
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/test")
|
||||||
|
public class TestApiController {
|
||||||
|
|
||||||
|
@Operation(summary = "admin test", description = "admin test api")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회",
|
||||||
|
content = @Content(schema = @Schema(implementation = String.class))),
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "403",
|
||||||
|
description = "권한 없음",
|
||||||
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
|
})
|
||||||
|
@GetMapping("/admin")
|
||||||
|
public String admin() {
|
||||||
|
return "I am administrator";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "label test", description = "label test api")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회",
|
||||||
|
content = @Content(schema = @Schema(implementation = String.class))),
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "403",
|
||||||
|
description = "권한 없음",
|
||||||
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
|
})
|
||||||
|
@GetMapping("/label")
|
||||||
|
public String label() {
|
||||||
|
return "Labeling is available.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "review test", description = "review test api")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회",
|
||||||
|
content = @Content(schema = @Schema(implementation = String.class))),
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "403",
|
||||||
|
description = "권한 없음",
|
||||||
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
|
})
|
||||||
|
@GetMapping("/review")
|
||||||
|
public String review() {
|
||||||
|
return "Review is available.";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,8 +38,10 @@ spring:
|
|||||||
|
|
||||||
jwt:
|
jwt:
|
||||||
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
|
secret: "kamco_token_9b71e778-19a3-4c1d-97bf-2d687de17d5b"
|
||||||
access-token-validity-in-ms: 86400000 # 1일
|
#access-token-validity-in-ms: 86400000 # 1일
|
||||||
refresh-token-validity-in-ms: 604800000 # 7일
|
#refresh-token-validity-in-ms: 604800000 # 7일
|
||||||
|
access-token-validity-in-ms: 60000 # 1분
|
||||||
|
refresh-token-validity-in-ms: 300000 # 5분
|
||||||
|
|
||||||
token:
|
token:
|
||||||
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
|
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
|
||||||
|
|||||||
Reference in New Issue
Block a user