사용자등록 추가, 추론결과 dashboard 수정

This commit is contained in:
2025-11-26 17:07:08 +09:00
parent 7e26a31d67
commit 704173840f
17 changed files with 246 additions and 62 deletions

View File

@@ -1,15 +1,55 @@
package com.kamco.cd.kamcoback.auth;
import com.kamco.cd.kamcoback.auth.dto.AuthDto;
import com.kamco.cd.kamcoback.auth.service.AuthService;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
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 jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "사용자 관리", description = "사용자 관리 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/auth")
public class AuthApiController {
@PostMapping("/signup")
public void signup() {
private final AuthService authService;
@Operation(summary = "사용자 등록", description = "사용자를 등록 합니다.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "사용자 등록 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/signup")
public ApiResponseDto<Long> signup(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "사용자 정보",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = AuthDto.Signup.class)))
@RequestBody
@Valid
AuthDto.Signup signup) {
return ApiResponseDto.createOK(authService.signup(signup));
}
}

View File

@@ -1,29 +1,69 @@
package com.kamco.cd.kamcoback.auth.dto;
import lombok.AllArgsConstructor;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
@RequiredArgsConstructor
public class AuthDto {
@Getter
public static class Signup {
@Setter
public static class Basic {
private String userAuth;
private String userNm;
private String userId;
private String userPw;
private String empId;
private String userEmail;
public Basic(String userAuth, String userNm, String userId, String empId, String userEmail) {
this.userAuth = userAuth;
this.userNm = userNm;
this.userId = userId;
this.empId = empId;
this.userEmail = userEmail;
}
}
@Schema(name = "Signup", description = "사용자 등록 정보")
@Getter
@Setter
public static class Signup {
@Schema(description = "구분", example = "관리자/라벨러/검수자 중 하나")
@NotBlank
private String userAuth;
@NotBlank
@Schema(description = "이름", example = "홍길동")
private String userNm;
@Schema(description = "ID", example = "gildong")
@NotBlank
private String userId;
@Schema(description = "PW", example = "password")
@NotBlank
private String userPw;
@Schema(description = "사번", example = "사번")
@NotBlank
private String empId;
@Schema(description = "이메일", example = "gildong@naver.com")
@NotBlank
private String userEmail;
public Signup(
String userAuth,
String userNm,
String userId,
String userPw,
String empId,
String userEmail
) {
String userEmail) {
this.userAuth = userAuth;
this.userNm = userNm;
this.userId = userId;
@@ -32,4 +72,10 @@ public class AuthDto {
this.userEmail = userEmail;
}
}
@Getter
public static class User {
String userId;
String userPw;
}
}

View File

@@ -0,0 +1,28 @@
package com.kamco.cd.kamcoback.auth.service;
import com.kamco.cd.kamcoback.auth.dto.AuthDto;
import com.kamco.cd.kamcoback.postgres.core.AuthCoreService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class AuthService {
private final AuthCoreService authCoreService;
private final PasswordEncoder passwordEncoder;
/**
* 사용자 등록
*
* @param signup
* @return
*/
@Transactional
public Long signup(AuthDto.Signup signup) {
signup.setUserPw(passwordEncoder.encode(signup.getUserPw()));
return authCoreService.signup(signup);
}
}

View File

@@ -2,8 +2,6 @@ package com.kamco.cd.kamcoback.inference;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Detail;
import com.kamco.cd.kamcoback.inference.service.InferenceResultService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -96,12 +94,7 @@ public class InferenceResultApiController {
@GetMapping("/detail")
public ApiResponseDto<InferenceResultDto.Detail> getInferenceDetail(
@Parameter(description = "목록 id", example = "1") @RequestParam Long id) {
// summary
InferenceResultDto.AnalResSummary summary =
inferenceResultService.getInferenceResultSummary(id);
// dashBoard
List<InferenceResultDto.Dashboard> dashboardList = this.getInferenceResultDashboard(id);
return ApiResponseDto.ok(new Detail(summary, dashboardList));
return ApiResponseDto.ok(inferenceResultService.getDetail(id));
}
@Operation(summary = "추론관리 분석결과 상세 목록", description = "추론관리 분석결과 상세 목록 geojson 데이터 조회")
@@ -139,14 +132,4 @@ public class InferenceResultApiController {
inferenceResultService.getInferenceResultGeomList(searchGeoReq);
return ApiResponseDto.ok(geomList);
}
/**
* 분석결과 상세 대시보드 조회
*
* @param id
* @return
*/
private List<Dashboard> getInferenceResultDashboard(Long id) {
return inferenceResultService.getInferenceResultBasic(id);
}
}

View File

@@ -188,10 +188,12 @@ public class InferenceResultDto {
public static class Detail {
AnalResSummary summary;
List<Dashboard> dashboard;
Long totalCnt;
public Detail(AnalResSummary summary, List<Dashboard> dashboard) {
public Detail(AnalResSummary summary, List<Dashboard> dashboard, Long totalCnt) {
this.summary = summary;
this.dashboard = dashboard;
this.totalCnt = totalCnt;
}
}

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.inference.service;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Detail;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService;
import java.util.List;
import lombok.RequiredArgsConstructor;
@@ -57,4 +58,21 @@ public class InferenceResultService {
InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultCoreService.getInferenceResultGeomList(searchGeoReq);
}
/**
* 분석결과 상제 정보 Summary, DashBoard
*
* @param id
* @return
*/
public Detail getDetail(Long id) {
// summary
InferenceResultDto.AnalResSummary summary = this.getInferenceResultSummary(id);
// 탐지건수 dashBoard
List<InferenceResultDto.Dashboard> dashboardList = this.getInferenceResultBasic(id);
// 전체 탐지건수
Long totalCnt = dashboardList.stream().mapToLong(Dashboard::getClassAfterCnt).sum();
return new Detail(summary, dashboardList, totalCnt);
}
}

View File

@@ -22,12 +22,9 @@ public class QuerydslOrderUtil {
sort -> {
Order order = sort.isAscending() ? Order.ASC : Order.DESC;
// PathBuilder.get()는 컬럼명(String)을 동적 Path로 반환
return new OrderSpecifier<>(order, entityPath.get(sort.getProperty(), Comparable.class));
return new OrderSpecifier<>(
order, entityPath.get(sort.getProperty(), Comparable.class));
})
.toArray(OrderSpecifier[]::new);
}
}

View File

@@ -0,0 +1,26 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.auth.dto.AuthDto;
import com.kamco.cd.kamcoback.postgres.repository.auth.AuthRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AuthCoreService {
private final AuthRepository authRepository;
/**
* 사용자 등록
*
* @param signup
* @return
*/
public Long signup(AuthDto.Signup signup) {
if (authRepository.findByUserId(signup.getUserId()).isPresent()) {
new EntityNotFoundException("중복된 아이디가 있습니다. " + signup.getUserId());
}
return authRepository.signup(signup);
}
}

View File

@@ -4,9 +4,8 @@ import com.kamco.cd.kamcoback.log.dto.ErrorLogDto;
import com.kamco.cd.kamcoback.log.dto.EventType;
import com.kamco.cd.kamcoback.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import java.time.ZonedDateTime;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

View File

@@ -6,14 +6,13 @@ import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.Map;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.util.Map;
@Getter
@Setter
@Entity

View File

@@ -7,6 +7,7 @@ import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
@@ -17,12 +18,17 @@ import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_user")
@Table(
name = "tb_user",
uniqueConstraints = {@UniqueConstraint(name = "ux_tb_user_user_id", columnNames = "user_id")})
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_user_id_gen")
@SequenceGenerator(name = "tb_user_id_gen", sequenceName = "tb_user_user_uid_seq", allocationSize = 1)
@SequenceGenerator(
name = "tb_user_id_gen",
sequenceName = "tb_user_user_uid_seq",
allocationSize = 1)
@Column(name = "user_uid", nullable = false)
private Long id;
@@ -77,5 +83,4 @@ public class UserEntity {
@NotNull
@Column(name = "emp_id", nullable = false)
private String empId;
}

View File

@@ -3,6 +3,4 @@ package com.kamco.cd.kamcoback.postgres.repository.auth;
import com.kamco.cd.kamcoback.postgres.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuthRepository extends JpaRepository<UserEntity, Long>, AuthRepositoryCustom {
}
public interface AuthRepository extends JpaRepository<UserEntity, Long>, AuthRepositoryCustom {}

View File

@@ -5,5 +5,7 @@ import com.kamco.cd.kamcoback.postgres.entity.UserEntity;
import java.util.Optional;
public interface AuthRepositoryCustom {
Optional<UserEntity> signup(AuthDto.Signup signup);
Long signup(AuthDto.Signup signup);
Optional<UserEntity> findByUserId(String userId);
}

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.kamcoback.postgres.repository.auth;
import com.kamco.cd.kamcoback.auth.dto.AuthDto;
import com.kamco.cd.kamcoback.postgres.entity.QUserEntity;
import com.kamco.cd.kamcoback.postgres.entity.UserEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.Optional;
@@ -11,10 +12,44 @@ import org.springframework.stereotype.Repository;
@RequiredArgsConstructor
public class AuthRepositoryImpl implements AuthRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QUserEntity userEntity = QUserEntity.userEntity;
/**
* 사용자 등록
*
* @param signup
* @return
*/
@Override
public Optional<UserEntity> signup(AuthDto.Signup signup) {
// queryFactory.insert()
return Optional.empty();
public Long signup(AuthDto.Signup signup) {
return queryFactory
.insert(userEntity)
.columns(
userEntity.userAuth,
userEntity.userId,
userEntity.userNm,
userEntity.userPw,
userEntity.userEmail,
userEntity.empId)
.values(
signup.getUserAuth(),
signup.getUserId(),
signup.getUserNm(),
signup.getUserPw(),
signup.getUserEmail(),
signup.getEmpId())
.execute();
}
/**
* 유저 아이디 조회
*
* @param userId
* @return
*/
@Override
public Optional<UserEntity> findByUserId(String userId) {
return Optional.ofNullable(
queryFactory.selectFrom(userEntity).where(userEntity.userId.eq(userId)).fetchOne());
}
}

View File

@@ -52,10 +52,13 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
modelMngEntity.modelCate,
modelVerEntity.id.as("modelVerUid"),
modelVerEntity.modelVer,
Expressions.stringTemplate("fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.usedState), //사용여부 한글 명칭
Expressions.stringTemplate("fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.modelState), //모델상태 한글 명칭
Expressions.stringTemplate(
"fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.usedState), // 사용여부 한글 명칭
Expressions.stringTemplate(
"fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.modelState), // 모델상태 한글 명칭
modelVerEntity.qualityProb,
Expressions.stringTemplate("fn_codenm_to_misc({0}, {1})", 52, modelVerEntity.deployState), //배포상태 한글 명칭
Expressions.stringTemplate(
"fn_codenm_to_misc({0}, {1})", 52, modelVerEntity.deployState), // 배포상태 한글 명칭
modelVerEntity.modelPath))
.from(modelMngEntity)
.innerJoin(modelVerEntity)
@@ -82,8 +85,11 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", modelVerEntity.createdDate)
.as("createdDttm"),
Expressions.stringTemplate("fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.usedState), //사용여부 한글 명칭
Expressions.stringTemplate("fn_codenm_to_misc({0}, {1})", 52, modelVerEntity.deployState), //배포상태 한글 명칭
Expressions.stringTemplate(
"fn_codenm_to_misc({0}, {1})", 51, modelVerEntity.usedState), // 사용여부 한글 명칭
Expressions.stringTemplate(
"fn_codenm_to_misc({0}, {1})",
52, modelVerEntity.deployState), // 배포상태 한글 명칭
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", modelDeployHstEntity.deployDttm)
.as("deployDttm")))