Initial commit

This commit is contained in:
jooho
2021-10-20 17:12:00 +09:00
parent 0c884beff8
commit 8caa4bbc5a
487 changed files with 44198 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="portal-service">
<properties>
<!-- 캐쉬 기능. 이게 true가 되어 있으면 이 프로젝틀르 통하지 않는 query는 반영이 늦을 수 있음 -->
<property name="eclipselink.query-results-cache" value="false" />
<!-- 데이터 베이스 연결 상의 로그 레벨 설정 -->
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.logging.parameters" value="true" />
<!-- driver 패키지 설정 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<!-- database 설정 -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.100.148:3306/msaportal" />
<!-- 접속 id -->
<property name="javax.persistence.jdbc.user" value="msaportal" />
<!-- 접속 password -->
<property name="javax.persistence.jdbc.password" value="msaportal01" />
</properties>
</persistence-unit>
</persistence>

View File

@@ -0,0 +1,21 @@
package org.egovframe.cloud.portalservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages={"org.egovframe.cloud.common", "org.egovframe.cloud.servlet", "org.egovframe.cloud.portalservice"}) // org.egovframe.cloud.common package 포함하기 위해
@EntityScan({"org.egovframe.cloud.servlet.domain", "org.egovframe.cloud.portalservice.domain"})
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class PortalServiceApplication {
public static void main(String[] args) {
SpringApplication.run(PortalServiceApplication.class, args);
}
}

View File

@@ -0,0 +1,65 @@
package org.egovframe.cloud.portalservice.api;
import lombok.RequiredArgsConstructor;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* org.egovframe.cloud.portalservice.api.PortalApiController
* <p>
* 상태 확인 요청을 처리하는 REST API Controller
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/06/30
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/06/30 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@RestController
public class PortalApiController {
private final Environment env;
/**
* 포털 서비스 상태 확인
*
* @return
*/
@GetMapping("/actuator/health-portal")
public String status() {
return String.format("GET Portal Service on" +
"\n local.server.port :" + env.getProperty("local.server.port")
+ "\n token expiration time :" + env.getProperty("token.expiration_time")
+ "\n egov.server.ip :" + env.getProperty("egov.server.ip")
+ "\n spring.datasource.username :" + env.getProperty("spring.datasource.username")
+ "\n spring.profiles.active :" + env.getProperty("spring.profiles.active")
+ "\n spring.cloud.config.label :" + env.getProperty("spring.cloud.config.label")
+ "\n spring.cloud.config.uri :" + env.getProperty("spring.cloud.config.uri")
+ "\n egov.message :" + env.getProperty("egov.message")
);
}
/**
* 포털 서비스 상태 확인
*
* @return
*/
@PostMapping("/actuator/health-portal")
public String poststatus() {
return String.format("POST Portal Service on" +
"\n local.server.port :" + env.getProperty("local.server.port")
+ "\n token expiration time :" + env.getProperty("token.expiration_time")
+ "\n egov.server.ip :" + env.getProperty("egov.server.ip")
+ "\n spring.datasource.username :" + env.getProperty("spring.datasource.username")
+ "\n egov.message :" + env.getProperty("egov.message")
);
}
}

View File

@@ -0,0 +1,309 @@
package org.egovframe.cloud.portalservice.api.attachment;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.common.exception.BusinessMessageException;
import org.egovframe.cloud.portalservice.api.attachment.dto.*;
import org.egovframe.cloud.portalservice.service.attachment.AttachmentService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.attachment.AttachmentApiController
* <p>
* 첨부파일 API controller class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Slf4j
@RequiredArgsConstructor
@RestController
public class AttachmentApiController {
private final AttachmentService attachmentService;
/**
* 첨부파일 업로드 - 단건
* 물리적 파일에 대해 업로드만 진행 (.temp)
* 추후 저장 필요
*
* @param file
* @return
* @throws Exception
*/
@PostMapping(value = "/api/v1/upload")
public AttachmentFileResponseDto upload(@RequestParam("file") MultipartFile file) {
return attachmentService.uploadFile(file);
}
/**
* 첨부파일 업로드 - 여러 건
* 물리적 파일에 대해 업로드만 진행 (.temp)
* 추후 저장 필요
*
* @param files
* @return
*/
@PostMapping(value = "/api/v1/upload/multi")
public List<AttachmentFileResponseDto> uploadMulti(@RequestParam("files") List<MultipartFile> files) {
return attachmentService.uploadFiles(files);
}
/**
* 에디터에서 파일 업로드
* 현재 이미지만 적용
*
* @param editorRequestDto
* @return
*/
@PostMapping(value = "/api/v1/upload/editor")
public AttachmentEditorResponseDto uploadEditor(@RequestBody AttachmentBase64RequestDto editorRequestDto) {
return attachmentService.uploadEditor(editorRequestDto);
}
/**
* 에디터에서 파일 경로(명) 이미지 load
*
* @param imagename
* @return
* @throws IOException
*/
@GetMapping(value = "/api/v1/images/editor/{imagename}")
public ResponseEntity<byte[]> loadImages(@PathVariable("imagename") String imagename) {
AttachmentImageResponseDto image = attachmentService.loadImage(imagename);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(image.getMimeType()))
.body(image.getData());
}
/**
* unique id로 이미지 태그에서 이미지 load
*
* @param uniqueId
* @return
*/
@GetMapping(value = "/api/v1/images/{uniqueId}")
public ResponseEntity<byte[]> loadImagesByUniqueId(@PathVariable String uniqueId) {
AttachmentImageResponseDto image = attachmentService.loadImageByUniqueId(uniqueId);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(image.getMimeType()))
.body(image.getData());
}
/**
* 첨부파일 다운로드
*
* @param uniqueId
* @return
* @throws IOException
*/
@GetMapping(value = "/api/v1/download/{uniqueId}")
public ResponseEntity<?> downloadFile(@PathVariable String uniqueId) {
AttachmentDownloadResponseDto downloadFile = attachmentService.downloadFile(uniqueId);
String mimeType = null;
try {
// get mime type
URLConnection connection = new URL(downloadFile.getFile().getURL().toString()).openConnection();
mimeType = connection.getContentType();
} catch (IOException ex) {
log.error("download fail", ex);
throw new BusinessMessageException("Sorry. download fail... \uD83D\uDE3F");
}
if (mimeType == null) {
mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
.filename(downloadFile.getOriginalFileName(), StandardCharsets.UTF_8)
.build();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, mimeType);
headers.setContentDisposition(contentDisposition);
return ResponseEntity.ok()
.headers(headers)
.body(downloadFile.getFile());
}
/**
* 첨부파일 코드로 첨부파일 목록 조회
*
* @param attachmentCode
* @return
*/
@GetMapping(value = "/api/v1/attachments/{attachmentCode}")
public List<AttachmentResponseDto> findByCode(@PathVariable String attachmentCode) {
return attachmentService.findByCode(attachmentCode);
}
/**
* 첨부파일 저장 - 물리적 파일은 .temp로 저장 된 후 호출되어야 함
* 새롭게 attachment code를 생성해야 하는 경우
*
* @param saveRequestDtoList
* @return 새로 생성한 첨부파일 code
*/
@PostMapping(value = "/api/v1/attachments/file")
public String save(@RequestBody List<AttachmentTempSaveRequestDto> saveRequestDtoList) {
return attachmentService.save(saveRequestDtoList);
}
/**
* 첨부파일 저장 - 물리적 파일은 .temp로 저장 된 후 호출되어야 함
* 이미 attachment code 가 있는 경우 seq만 새로 생성해서 저장
* or
* isDelete = true 인 경우 삭제 여부 Y
*
* @param saveRequestDtoList
* @return
*/
@PutMapping(value = "/api/v1/attachments/file/{attachmentCode}")
public String saveByCode(@PathVariable String attachmentCode, @RequestBody List<AttachmentTempSaveRequestDto> saveRequestDtoList) {
return attachmentService.saveByCode(attachmentCode, saveRequestDtoList);
}
/**
* 관리자 - 전체 첨부파일 목록 조회
*
* @param searchRequestDto
* @param pageable
* @return
*/
@GetMapping(value = "/api/v1/attachments")
public Page<AttachmentResponseDto> search(RequestDto searchRequestDto, Pageable pageable) {
return attachmentService.search(searchRequestDto, pageable);
}
/**
* 관리자 - 삭제여부 토글
*
* @param uniqueId
* @param isDelete
* @return
*/
@PutMapping(value = "/api/v1/attachments/{uniqueId}/{isDelete}")
public String toggleDelete(@PathVariable String uniqueId, @PathVariable boolean isDelete) {
return attachmentService.toggleDelete(uniqueId, isDelete);
}
/**
* 관리자 - 하나의 파일 삭제
* 물리적 파일 삭제
*
* @param uniqueId
*/
@DeleteMapping(value = "/api/v1/attachments/{uniqueId}")
public void delete(@PathVariable String uniqueId) {
attachmentService.delete(uniqueId);
}
/**
* 첨부파일 저장
* 새롭게 attachment code를 생성해야 하는 경우
*
* @param files
* @param uploadRequestDto
* @return
*/
@PostMapping(value = "/api/v1/attachments/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public String uploadAndSave(@RequestPart(value = "files", required = true) List<MultipartFile> files,
@RequestPart(value = "info", required = false) AttachmentUploadRequestDto uploadRequestDto) {
return attachmentService.uploadAndSave(files, uploadRequestDto);
}
/**
* 첨부파일 저장
* 이미 attachment code 가 있는 경우 이므로 seq만 새로 생성해서 저장
* or
* isDelete = true 인 경우 삭제 여부 Y
*
* @param files
* @param attachmentCode
* @param uploadRequestDto
* @param saveRequestDtoList
* @return
*/
@PutMapping(value = "/api/v1/attachments/upload/{attachmentCode}", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public String uploadAndUpdate(@PathVariable String attachmentCode,
@RequestPart(value = "files", required = true) List<MultipartFile> files,
@RequestPart(value = "info", required = true) AttachmentUploadRequestDto uploadRequestDto,
@RequestPart(value = "list", required = false) List<AttachmentUpdateRequestDto> saveRequestDtoList) {
return attachmentService.uploadAndUpdate(files, attachmentCode, uploadRequestDto, saveRequestDtoList);
}
/**
* 첨부파일 저장 - 업로드 없이 기존 파일만 삭제
* isDelete = true 인 경우 삭제 여부 Y
*
* @param attachmentCode
* @param uploadRequestDto
* @param updateRequestDtoList
* @return
*/
@PutMapping(value = "/api/v1/attachments/{attachmentCode}", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public String update(@PathVariable String attachmentCode,
@RequestPart(value = "info") AttachmentUploadRequestDto uploadRequestDto,
@RequestPart(value = "list") List<AttachmentUpdateRequestDto> updateRequestDtoList){
return attachmentService.uploadAndUpdate(null, attachmentCode,
uploadRequestDto, updateRequestDtoList);
}
/**
* attachmentCode로 해당하는 모든 첨부파일의 entity 정보 업데이트
* 신규 entity의 경우 entity가 저장 된 후 entity id가 생성되므로
* entity 저장 후 해당 api 호출하여 entity 정보를 업데이트 해준다.
*
* @param attachmentCode
* @param uploadRequestDto
* @return
*/
@PutMapping("/api/v1/attachments/{attachmentCode}/info")
public String updateEntity(@PathVariable String attachmentCode,
@RequestBody AttachmentUploadRequestDto uploadRequestDto) {
return attachmentService.updateEntity(attachmentCode, uploadRequestDto);
}
/**
* 첨부파일 저장 후 기능 저장 시 오류 날 경우
* 해당 첨부파일 코드에 조회되는 첨부파일 목록 전부 삭제
* rollback
*
* @param attachmentCode
*/
@DeleteMapping("/api/v1/attachments/{attachmentCode}/children")
public void deleteAllEmptyEntity(@PathVariable String attachmentCode) {
attachmentService.deleteAllEmptyEntity(attachmentCode);
}
}

View File

@@ -0,0 +1,45 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentBase64RequestDto
* <p>
* 첨부파일 Base64 업로드 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentBase64RequestDto {
private String fieldName;
private String fileType;
private String fileBase64;
private String originalName;
private Long size;
@Builder
public AttachmentBase64RequestDto(String fieldName, String fileType, String fileBase64, String originalName, Long size) {
this.fieldName = fieldName;
this.fileType = fileType;
this.fileBase64 = fileBase64;
this.originalName = originalName;
this.size = size;
}
}

View File

@@ -0,0 +1,35 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.core.io.Resource;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentDownloadResponseDto
* <p>
* 첨부파일 다운로드 시 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class AttachmentDownloadResponseDto {
private String originalFileName;
private Resource file;
@Builder
public AttachmentDownloadResponseDto(String originalFileName, Resource file) {
this.originalFileName = originalFileName;
this.file = file;
}
}

View File

@@ -0,0 +1,42 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentEditorResponseDto
* <p>
* 첨부파일 에디터 업로드 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentEditorResponseDto extends AttachmentUploadResponseDto {
private int uploaded;
private String url;
@Builder
public AttachmentEditorResponseDto(String originalFileName, String message, String fileType, long size, int uploaded, String url) {
this.originalFileName = originalFileName;
this.message = message;
this.fileType = fileType;
this.size = size;
this.uploaded = uploaded;
this.url = url;
}
}

View File

@@ -0,0 +1,39 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentFileResponseDto
* <p>
* 첨부파일 업로드 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentFileResponseDto extends AttachmentUploadResponseDto {
private String physicalFileName;
@Builder
public AttachmentFileResponseDto(String originalFileName, String message, String fileType, long size, String physicalFileName) {
this.originalFileName = originalFileName;
this.message = message;
this.fileType = fileType;
this.size = size;
this.physicalFileName = physicalFileName;
}
}

View File

@@ -0,0 +1,36 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentImageResponseDto
* <p>
* 이미지태그에 대한 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class AttachmentImageResponseDto {
private String mimeType;
private byte[] data;
@Builder
public AttachmentImageResponseDto(String mimeType, byte[] data) {
this.mimeType = mimeType;
this.data = data;
}
}

View File

@@ -0,0 +1,61 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.attachment.Attachment;
import java.time.LocalDateTime;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentResponseDto
* <p>
* 첨부파일 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentResponseDto {
private String code;
private Long seq;
private String id;
private String physicalFileName;
private String originalFileName;
private Long size;
private String fileType;
private Long downloadCnt;
private Boolean isDelete;
private String entityName;
private String entityId;
private LocalDateTime createDate;
@Builder
public AttachmentResponseDto(Attachment attachment) {
this.code = attachment.getAttachmentId().getCode();
this.seq = attachment.getAttachmentId().getSeq();
this.id = attachment.getUniqueId();
this.physicalFileName = attachment.getPhysicalFileName();
this.originalFileName = attachment.getOriginalFileName();
this.size = attachment.getSize();
this.fileType = attachment.getFileType();
this.downloadCnt = attachment.getDownloadCnt();
this.isDelete = attachment.getIsDelete();
this.entityName = attachment.getEntityName();
this.entityId = attachment.getEntityId();
this.createDate = attachment.getCreatedDate();
}
}

View File

@@ -0,0 +1,52 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentSaveRequestDto
* <p>
* 첨부파일 도메인 저장에대한 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentTempSaveRequestDto {
private String uniqueId;
private String physicalFileName;
private String originalName;
private Long size;
private String fileType;
private String entityName;
private String entityId;
private boolean isDelete;
@Builder
public AttachmentTempSaveRequestDto(String uniqueId, String physicalFileName,
String originalName, Long size,
String fileType, String entityName,
String entityId, boolean isDelete) {
this.uniqueId = uniqueId;
this.physicalFileName = physicalFileName;
this.originalName = originalName;
this.size = size;
this.fileType = fileType;
this.entityName = entityName;
this.entityId = entityId;
this.isDelete = isDelete;
}
}

View File

@@ -0,0 +1,35 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.*;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentUpdateRequestDto
* <p>
* 첨부파일 수정 저장 시 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentUpdateRequestDto {
private String uniqueId;
private Boolean isDelete;
@Builder
public AttachmentUpdateRequestDto(String uniqueId, Boolean isDelete) {
this.uniqueId = uniqueId;
this.isDelete = isDelete;
}
}

View File

@@ -0,0 +1,38 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentUploadRequestDto
* <p>
* 첨부파일 업로드 저장 시 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentUploadRequestDto {
private String entityName;
private String entityId;
@Builder
public AttachmentUploadRequestDto(String entityName, String entityId) {
this.entityName = entityName;
this.entityId = entityId;
}
}

View File

@@ -0,0 +1,32 @@
package org.egovframe.cloud.portalservice.api.attachment.dto;
import lombok.*;
/**
* org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentUploadResponseDto
* <p>
* 첨부파일 업로드에 대한 응답 dto 추상 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class AttachmentUploadResponseDto {
protected String originalFileName;
protected String message;
protected String fileType;
protected long size;
}

View File

@@ -0,0 +1,148 @@
package org.egovframe.cloud.portalservice.api.banner;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerImageResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerListResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerRequestDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerSaveRequestDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerUpdateRequestDto;
import org.egovframe.cloud.portalservice.service.banner.BannerService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.banner.BannerApiController
* <p>
* 배너 Rest API 컨트롤러 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@RestController
public class BannerApiController {
/**
* 배너 서비스
*/
private final BannerService bannerService;
/**
* 배너 페이지 목록 조회
*
* @param requestDto 요청 DTO
* @param pageable 페이지 정보
* @return Page<BannerListResponseDto> 페이지 배너 목록 응답 DTO
*/
@GetMapping("/api/v1/banners")
public Page<BannerListResponseDto> findPage(BannerRequestDto requestDto,
@PageableDefault(sort = "banner_no", direction = Sort.Direction.DESC) Pageable pageable) {
return bannerService.findPage(requestDto, pageable);
}
/**
* 유형별 배너 목록 조회
*
* @param siteId 사이트 ID
* @param bannerTypeCodes 배너 유형 코드 목록
* @param bannerCount 배너 수
* @return Map<String, List<BannerImageResponseDto>> 배너 유형 코드별 배너 이미지 응답 DTO Map
*/
@GetMapping("/api/v1/{siteId}/banners/{bannerTypeCodes}/{bannerCount}")
public Map<String, List<BannerImageResponseDto>> findUseList(@PathVariable Long siteId, @PathVariable List<String> bannerTypeCodes, @PathVariable Integer bannerCount) {
return bannerService.findList(bannerTypeCodes, bannerCount, true, siteId);
}
/**
* 배너 단건 조회
*
* @param bannerNo 배너 번호
* @return BannerResponseDto 배너 상세 응답 DTO
*/
@GetMapping("/api/v1/banners/{bannerNo}")
public BannerResponseDto findById(@PathVariable Integer bannerNo) {
return bannerService.findById(bannerNo);
}
/**
* 배너 다음 정렬 순서 조회
*
* @param siteId siteId
* @return Integer 다음 정렬 순서
*/
@GetMapping("/api/v1/banners/{siteId}/sort-seq/next")
public Integer findNextSortSeq(@PathVariable Long siteId) {
return bannerService.findNextSortSeq(siteId);
}
/**
* 배너 등록
*
* @param requestDto 배너 등록 요청 DTO
* @return BannerResponseDto 배너 상세 응답 DTO
*/
@PostMapping("/api/v1/banners")
public BannerResponseDto save(@RequestBody @Valid BannerSaveRequestDto requestDto) {
return bannerService.save(requestDto);
}
/**
* 배너 수정
*
* @param bannerNo 배너 번호
* @param requestDto 배너 수정 요청 DTO
* @return BannerResponseDto 배너 상세 응답 DTO
*/
@PutMapping("/api/v1/banners/{bannerNo}")
public BannerResponseDto update(@PathVariable Integer bannerNo, @RequestBody @Valid BannerUpdateRequestDto requestDto) {
return bannerService.update(bannerNo, requestDto);
}
/**
* 배너 사용 여부 수정
*
* @param bannerNo 배너 번호
* @param useAt 사용 여부
* @return BannerResponseDto 배너 상세 응답 DTO
*/
@PutMapping("/api/v1/banners/{bannerNo}/{useAt}")
public BannerResponseDto updateUseAt(@PathVariable Integer bannerNo, @PathVariable Boolean useAt) {
return bannerService.updateUseAt(bannerNo, useAt);
}
/**
* 배너 삭제
*
* @param bannerNo 배너 번호
*/
@DeleteMapping("/api/v1/banners/{bannerNo}")
public void delete(@PathVariable Integer bannerNo) {
bannerService.delete(bannerNo);
}
}

View File

@@ -0,0 +1,96 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* org.egovframe.cloud.portalservice.api.banner.dto.BannerImageResponseDto
* <p>
* 배너 이미지 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/09/03
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/09/03 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class BannerImageResponseDto implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -5701020612682455280L;
/**
* 배너 번호
*/
private Integer bannerNo;
/**
* 배너 구분 코드
*/
private String bannerTypeCode;
/**
* 배너 제목
*/
private String bannerTitle;
/**
* 첨부파일 코드
*/
private String attachmentCode;
private String uniqueId;
/**
* url 주소
*/
private String urlAddr;
/**
* 새 창 여부
*/
private Boolean newWindowAt;
/**
* 배너 내용
*/
private String bannerContent;
/**
* 배너 목록 응답 DTO 생성자
*
* @param bannerNo 배너 번호
* @param bannerTypeCode 배너 구분 코드
* @param bannerTitle 배너 제목
* @param attachmentCode 첨부파일 코드
* @param uniqueId 첨부파일 unique 코드
* @param urlAddr url 주소
* @param newWindowAt 새 창 여부
* @param bannerContent 배너 내용
*/
@QueryProjection
public BannerImageResponseDto(Integer bannerNo, String bannerTypeCode, String bannerTitle, String attachmentCode, String uniqueId, String urlAddr, Boolean newWindowAt, String bannerContent) {
this.bannerNo = bannerNo;
this.bannerTypeCode = bannerTypeCode;
this.bannerTitle = bannerTitle;
this.attachmentCode = attachmentCode;
this.uniqueId = uniqueId;
this.urlAddr = urlAddr;
this.newWindowAt = newWindowAt;
this.bannerContent = bannerContent;
}
}

View File

@@ -0,0 +1,93 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.content.dto.BannerListResponseDto
* <p>
* 배너 목록 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class BannerListResponseDto implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -2944698753371861587L;
/**
* 배너 번호
*/
private Integer bannerNo;
/**
* 배너 구분 코드
*/
private String bannerTypeCode;
/**
* 배너 구분 코드 명
*/
private String bannerTypeCodeName;
/**
* 배너 제목
*/
private String bannerTitle;
/**
* 사용 여부
*/
private Boolean useAt;
/**
* 수정 일시
*/
private LocalDateTime createdDate;
/**
* site 명
*/
private String siteName;
/**
* 배너 목록 응답 DTO 생성자
*
* @param bannerNo 배너 번호
* @param bannerTypeCode 배너 구분 코드
* @param bannerTypeCodeName 배너 구분 코드 명
* @param bannerTitle 배너 제목
* @param useAt 사용 여부
* @param createdDate 생성 일시
*/
@QueryProjection
public BannerListResponseDto(Integer bannerNo, String bannerTypeCode, String bannerTypeCodeName, String bannerTitle, Boolean useAt, LocalDateTime createdDate, String siteName) {
this.bannerNo = bannerNo;
this.bannerTypeCode = bannerTypeCode;
this.bannerTypeCodeName = bannerTypeCodeName;
this.bannerTitle = bannerTitle;
this.useAt = useAt;
this.createdDate = createdDate;
this.siteName = siteName;
}
}

View File

@@ -0,0 +1,28 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import org.egovframe.cloud.common.dto.RequestDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.content.dto.BannerRequestDto
* <p>
* 배너 목록 요청 DTO 클래스
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/10/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/10/12 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class BannerRequestDto extends RequestDto {
private Long siteId;
}

View File

@@ -0,0 +1,108 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.banner.Banner;
/**
* org.egovframe.cloud.portalservice.api.content.dto.BannerResponseDto
* <p>
* 배너 상세 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class BannerResponseDto {
/**
* 배너 번호
*/
private Integer bannerNo;
/**
* 배너 구분 코드
*/
private String bannerTypeCode;
/**
* 배너 제목
*/
private String bannerTitle;
/**
* 첨부파일 코드
*/
private String attachmentCode;
/**
* url 주소
*/
private String urlAddr;
/**
* 새 창 여부
*/
private Boolean newWindowAt;
/**
* 배너 내용
*/
private String bannerContent;
/**
* 정렬 순서
*/
private Integer sortSeq;
/**
* site Id
*/
private Long siteId;
/**
* 배너 엔티티를 생성자로 주입 받아서 배너 상세 응답 DTO 속성 값 세팅
*
* @param entity 배너 엔티티
*/
public BannerResponseDto(Banner entity) {
this.bannerNo = entity.getBannerNo();
this.bannerTypeCode = entity.getBannerTypeCode();
this.bannerTitle = entity.getBannerTitle();
this.attachmentCode = entity.getAttachmentCode();
this.urlAddr = entity.getUrlAddr();
this.newWindowAt = entity.getNewWindowAt();
this.bannerContent = entity.getBannerContent();
this.sortSeq = entity.getSortSeq();
this.siteId = entity.getSite().getId();
}
/**
* 배너 상세 응답 DTO 속성 값으로 배너 엔티티 빌더를 사용하여 객체 생성
*
* @return Banner 배너 엔티티
*/
public Banner toEntity() {
return Banner.builder()
.bannerNo(bannerNo)
.bannerTypeCode(bannerTypeCode)
.bannerTitle(bannerTitle)
.attachmentCode(attachmentCode)
.urlAddr(urlAddr)
.newWindowAt(newWindowAt)
.bannerContent(bannerContent)
.sortSeq(sortSeq)
.build();
}
}

View File

@@ -0,0 +1,91 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import javax.validation.constraints.NotBlank;
import org.egovframe.cloud.portalservice.domain.banner.Banner;
import org.egovframe.cloud.portalservice.domain.menu.Site;
import lombok.Getter;
/**
* org.egovframe.cloud.portalservice.api.content.dto.BannerSaveRequestDto
* <p>
* 배너 등록 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@Getter
public class BannerSaveRequestDto {
/**
* 배너 구분 코드
*/
@NotBlank(message = "{banner.banner_type_code} {err.required}")
private String bannerTypeCode;
/**
* 배너 제목
*/
@NotBlank(message = "{banner.banner_title} {err.required}")
private String bannerTitle;
/**
* 첨부파일 코드
*/
@NotBlank(message = "{banner.attachment_code} {err.required}")
private String attachmentCode;
/**
* url 주소
*/
private String urlAddr;
/**
* 새 창 여부
*/
private Boolean newWindowAt;
/**
* 배너 내용
*/
private String bannerContent;
/**
* 정렬 순서
*/
private Integer sortSeq;
/**
* siteId
*/
private Long siteId;
/**
* 배너 등록 요청 DTO 속성 값으로 배너 엔티티 빌더를 사용하여 객체 생성
*
* @return Banner 배너 엔티티
*/
public Banner toEntity(Site site) {
return Banner.builder()
.bannerTypeCode(bannerTypeCode)
.bannerTitle(bannerTitle)
.attachmentCode(attachmentCode)
.urlAddr(urlAddr)
.newWindowAt(newWindowAt)
.bannerContent(bannerContent)
.sortSeq(sortSeq)
.site(site)
.build();
}
}

View File

@@ -0,0 +1,70 @@
package org.egovframe.cloud.portalservice.api.banner.dto;
import lombok.Getter;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.content.dto.BannerUpdateRequestDto
* <p>
* 배너 수정 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/08
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/08 jooho 최초 생성
* </pre>
*/
@Getter
public class BannerUpdateRequestDto {
/**
* 배너 구분 코드
*/
@NotBlank(message = "{banner.banner_type_code} {err.required}")
private String bannerTypeCode;
/**
* 배너 제목
*/
@NotBlank(message = "{banner.banner_title} {err.required}")
private String bannerTitle;
/**
* 첨부파일 코드
*/
@NotBlank(message = "{banner.attachment_code} {err.required}")
private String attachmentCode;
/**
* url 주소
*/
private String urlAddr;
/**
* 새 창 여부
*/
private Boolean newWindowAt;
/**
* 배너 내용
*/
private String bannerContent;
/**
* 정렬 순서
*/
private Integer sortSeq;
/**
* site Id
*/
private Long siteId;
}

View File

@@ -0,0 +1,120 @@
package org.egovframe.cloud.portalservice.api.code;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.code.dto.CodeListResponseDto;
import org.egovframe.cloud.portalservice.api.code.dto.CodeResponseDto;
import org.egovframe.cloud.portalservice.api.code.dto.CodeSaveRequestDto;
import org.egovframe.cloud.portalservice.api.code.dto.CodeUpdateRequestDto;
import org.egovframe.cloud.portalservice.domain.code.CodeRepository;
import org.egovframe.cloud.portalservice.service.code.CodeService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.code.CodeApiController
* <p>
* 공통코드 CRUD 요청을 처리하는 REST API Controller
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor // final이 선언된 모든 필드를 인자값으로 하는 생성자를 대신 생성하여, 빈을 생성자로 주입받게 한다.
@RestController
public class CodeApiController {
private final CodeService codeService;
private final CodeRepository codeRepository;
/**
* 공통코드 목록 조회
*
* @param requestDto
* @param pageable
* @return
*/
@GetMapping("/api/v1/codes")
public Page<CodeListResponseDto> findAllByKeyword(RequestDto requestDto, Pageable pageable) {
return codeRepository.findAllByKeyword(requestDto, pageable);
}
/**
* 공통코드 목록 - parentCodeId 가 없는 상위공통코드
*
* @return
*/
@GetMapping("/api/v1/codes-parent")
public List<CodeResponseDto> findAllParent() {
return codeRepository.findAllParent();
}
/**
* 공통코드 단건 조회
*
* @param codeId
* @return
*/
@GetMapping("/api/v1/codes/{codeId}")
public CodeResponseDto findByCodeId(@PathVariable String codeId) {
return codeService.findByCodeId(codeId);
}
/**
* 공통코드 등록
*
* @param requestDto
* @return
*/
@PostMapping("/api/v1/codes")
public String save(@RequestBody @Valid CodeSaveRequestDto requestDto) {
return codeService.save(requestDto);
}
/**
* 공통코드 수정
*
* @param codeId
* @param requestDto
* @return
*/
@PutMapping("/api/v1/codes/{codeId}")
public String update(@PathVariable String codeId, @RequestBody CodeUpdateRequestDto requestDto) {
return codeService.update(codeId, requestDto);
}
/**
* 사용여부 toggle
*
* @param codeId
* @param useAt
* @return
*/
@PutMapping("/api/v1/codes/{codeId}/toggle-use")
public String updateUseAt(@PathVariable String codeId, @RequestParam boolean useAt) {
return codeService.updateUseAt(codeId, useAt);
}
/**
* 공통코드 삭제
*
* @param codeId
*/
@DeleteMapping("/api/v1/codes/{codeId}")
public void delete(@PathVariable String codeId) {
codeService.delete(codeId);
}
}

View File

@@ -0,0 +1,141 @@
package org.egovframe.cloud.portalservice.api.code;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.portalservice.api.code.dto.*;
import org.egovframe.cloud.portalservice.domain.code.CodeRepository;
import org.egovframe.cloud.portalservice.service.code.CodeDetailService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.code.CodeApiController
* <p>
* 공통코드 CRUD 요청을 처리하는 REST API Controller
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor // final이 선언된 모든 필드를 인자값으로 하는 생성자를 대신 생성하여, 빈을 생성자로 주입받게 한다.
@RestController
public class CodeDetailApiController {
private final CodeDetailService codeDetailService;
private final CodeRepository codeRepository;
/**
* 공통코드 상세 목록 조회
*
* @param requestDto
* @param pageable
* @return
*/
@GetMapping("/api/v1/code-details")
public Page<CodeDetailListResponseDto> findAllByKeyword(CodeDetailRequestDto requestDto, Pageable pageable) {
return codeRepository.findAllDetailByKeyword(requestDto, pageable);
}
/**
* 부모공통코드의 상세 목록 조회
* 사용중인 공통코드만 조회한다
*
* @param parentCodeId
* @return
*/
@GetMapping("/api/v1/code-details/{parentCodeId}/codes")
public List<CodeDetailResponseDto> findDetailsByParentCodeIdUseAt(@PathVariable String parentCodeId) {
return codeRepository.findDetailsByParentCodeIdUseAt(parentCodeId);
}
/**
* 부모공통코드의 상세 목록 조회
* 사용여부가 false 로 변경된 경우에도 인자로 받은 공통코드를 목록에 포함되도록 한다
*
* @param parentCodeId
* @return
*/
@GetMapping("/api/v1/code-details/{parentCodeId}/codes/{codeId}")
public List<CodeDetailResponseDto> findDetailsUnionCodeIdByParentCodeId(@PathVariable String parentCodeId, @PathVariable String codeId) {
return codeRepository.findDetailsUnionCodeIdByParentCodeId(parentCodeId, codeId);
}
/**
* 공통코드 상세 단건 조회
*
* @param codeId
* @return
*/
@GetMapping("/api/v1/code-details/{codeId}")
public CodeDetailResponseDto findByCodeId(@PathVariable String codeId) {
return codeDetailService.findByCodeId(codeId);
}
/**
* 공통코드 부모코드 단건 조회
*
* @param codeId
* @return
*/
@GetMapping("/api/v1/code-details/{codeId}/parent")
public CodeResponseDto findParentByCodeId(@PathVariable String codeId) {
return codeRepository.findParentByCodeId(codeId);
}
/**
* 공통코드 상세 등록
*
* @param requestDto
* @return
*/
@PostMapping("/api/v1/code-details")
public String save(@RequestBody @Valid CodeDetailSaveRequestDto requestDto) {
return codeDetailService.save(requestDto);
}
/**
* 공통코드 상세 수정
*
* @param codeId
* @param requestDto
* @return
*/
@PutMapping("/api/v1/code-details/{codeId}")
public String update(@PathVariable String codeId, @RequestBody CodeDetailUpdateRequestDto requestDto) {
return codeDetailService.update(codeId, requestDto);
}
/**
* 사용여부 toggle
*
* @param codeId
* @param useAt
* @return
*/
@PutMapping("/api/v1/code-details/{codeId}/toggle-use")
public String updateUseAt(@PathVariable String codeId, @RequestParam boolean useAt) {
return codeDetailService.updateUseAt(codeId, useAt);
}
/**
* 공통코드 상세 삭제
*
* @param codeId
*/
@DeleteMapping("/api/v1/code-details/{codeId}")
public void delete(@PathVariable String codeId) {
codeDetailService.delete(codeId);
}
}

View File

@@ -0,0 +1,32 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeDetailListResponseDto
* <p>
* 공통코드 상세 목록 조회 응답 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeDetailListResponseDto {
private String parentCodeId; // 상위 코드ID
private String codeId; // 코드ID
private String codeName; // 코드 명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
}

View File

@@ -0,0 +1,30 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.egovframe.cloud.common.dto.RequestDto;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeDetailRequestDto
* <p>
* 공통코드 상세 조회 요청 파라미터 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@SuperBuilder
public class CodeDetailRequestDto extends RequestDto {
private String parentCodeId; // 상위 공통코드 ID
}

View File

@@ -0,0 +1,51 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeDetailResponseDto
* <p>
* 공통코드 상세 조회 응답 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeDetailResponseDto {
private String codeId; // 코드ID
private String parentCodeId; // 상위 코드ID
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
/**
* Entity의 필드 중 일부만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣는다.
* 굳이 모든 필드를 가진 생성자가 필요하지 않다.
*
* @param entity
*/
public CodeDetailResponseDto(Code entity) {
this.codeId = entity.getCodeId();
this.parentCodeId = entity.getParentCodeId();
this.codeName = entity.getCodeName();
this.codeDescription = entity.getCodeDescription();
this.sortSeq = entity.getSortSeq();
this.useAt = entity.getUseAt();
this.readonly = entity.getReadonly();
}
}

View File

@@ -0,0 +1,72 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeDetailSaveRequestDto
* <p>
* 공통코드 상세 등록 요청 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeDetailSaveRequestDto {
@NotBlank(message = "{code.parent_code_id}{valid.required}")
private String parentCodeId; // 상위 코드ID
@NotBlank(message = "{code.code_id}{valid.required}")
private String codeId; // 코드ID
@NotBlank(message = "{code.code_name}{valid.required}")
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
@Builder
public CodeDetailSaveRequestDto(String parentCodeId, String codeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt, Boolean readonly) {
this.parentCodeId = parentCodeId;
this.codeId = codeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
this.readonly = readonly;
}
/**
* SaveRequestDto 의 필드 값을 Entity 빌더를 사용하여 주입 후 Entity 를 리턴한다.
* SaveRequestDto 가 가지고 있는 Entity 의 필드만 세팅할 수 있게 된다.
*
* @return
*/
public Code toEntity() {
return Code.builder()
.parentCodeId(parentCodeId)
.codeId(codeId)
.codeName(codeName)
.codeDescription(codeDescription)
.sortSeq(sortSeq)
.useAt(useAt)
.readonly(readonly != null && readonly) // readonly 값이 없으면 기본값은 false 로 설정한다
.build();
}
}

View File

@@ -0,0 +1,64 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeDetailSaveRequestDto
* <p>
* 공통코드 상세 수정 요청 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeDetailUpdateRequestDto {
@NotBlank(message = "{code.parent_code_id}{valid.required}")
private String parentCodeId; // 상위 코드ID
@NotBlank(message = "{code.code_name}{valid.required}")
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
@Builder
public CodeDetailUpdateRequestDto(String parentCodeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt) {
this.parentCodeId = parentCodeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
}
/**
* SaveRequestDto 의 필드 값을 Entity 빌더를 사용하여 주입 후 Entity 를 리턴한다.
* SaveRequestDto 가 가지고 있는 Entity 의 필드만 세팅할 수 있게 된다.
*
* @return
*/
public Code toEntity() {
return Code.builder()
.parentCodeId(parentCodeId)
.codeName(codeName)
.codeDescription(codeDescription)
.sortSeq(sortSeq)
.useAt(useAt)
.build();
}
}

View File

@@ -0,0 +1,33 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeListResponseDto
* <p>
* 공통코드 목록 조회 응답 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeListResponseDto {
private String codeId; // 코드ID
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
private Long codeDetailCount; // 코드상세수
}

View File

@@ -0,0 +1,48 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeResponseDto
* <p>
* 공통코드 조회 응답 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeResponseDto {
private String codeId; // 코드ID
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
/**
* Entity의 필드 중 일부만 사용하므로 생성자로 Entity를 받아 필드에 값을 넣는다. 굳이 모든 필드를 가진 생성자가 필요하지 않다.
*
* @param entity
*/
public CodeResponseDto(Code entity) {
this.codeId = entity.getCodeId();
this.codeName = entity.getCodeName();
this.codeDescription = entity.getCodeDescription();
this.sortSeq = entity.getSortSeq();
this.useAt = entity.getUseAt();
this.readonly = entity.getReadonly();
}
}

View File

@@ -0,0 +1,65 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeSaveRequestDto
* <p>
* 공통코드 등록 요청 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeSaveRequestDto {
@NotBlank(message = "{code.code_id}{valid.required}")
private String codeId; // 코드ID
@NotBlank(message = "{code.code_name}{valid.required}")
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
@Builder
public CodeSaveRequestDto(String codeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt, Boolean readonly) {
this.codeId = codeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
this.readonly = readonly;
}
/**
* SaveRequestDto 의 필드 값을 Entity 빌더를 사용하여 주입 후 Entity 를 리턴한다.
* SaveRequestDto 가 가지고 있는 Entity 의 필드만 세팅할 수 있게 된다.
*
* @return
*/
public Code toEntity() {
return Code.builder()
.codeId(codeId)
.codeName(codeName)
.codeDescription(codeDescription)
.useAt(useAt)
.sortSeq(sortSeq)
.readonly(readonly != null && readonly) // readonly 값이 없으면 기본값은 false 로 설정한다
.build();
}
}

View File

@@ -0,0 +1,63 @@
package org.egovframe.cloud.portalservice.api.code.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.code.Code;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.code.dto.CodeUpdateRequestDto
* <p>
* 공통코드 수정 요청 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class CodeUpdateRequestDto {
@NotBlank(message = "{code.code_id}{valid.required}")
private String codeId; // 코드ID
@NotBlank(message = "{code.code_name}{valid.required}")
private String codeName; // 코드 명
private String codeDescription; // 코드 설명
private Integer sortSeq; // 정렬 순서
private Boolean useAt; // 사용 여부
@Builder
public CodeUpdateRequestDto(String codeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt) {
this.codeId = codeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
}
/**
* SaveRequestDto 의 필드 값을 Entity 빌더를 사용하여 주입 후 Entity 를 리턴한다.
* SaveRequestDto 가 가지고 있는 Entity 의 필드만 세팅할 수 있게 된다.
*
* @return
*/
public Code toEntity() {
return Code.builder()
.codeId(codeId)
.codeName(codeName)
.codeDescription(codeDescription)
.useAt(useAt)
.build();
}
}

View File

@@ -0,0 +1,108 @@
package org.egovframe.cloud.portalservice.api.content;
import javax.validation.Valid;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentListResponseDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentResponseDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentSaveRequestDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentUpdateRequestDto;
import org.egovframe.cloud.portalservice.service.content.ContentService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.content.ContentApiController
* <p>
* 컨텐츠 Rest API 컨트롤러 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@RestController
public class ContentApiController {
/**
* 컨텐츠 서비스
*/
private final ContentService contentService;
/**
* 컨텐츠 페이지 목록 조회
*
* @param requestDto 요청 DTO
* @param pageable 페이지 정보
* @return Page<ContentListResponseDto> 페이지 컨텐츠 목록 응답 DTO
*/
@GetMapping("/api/v1/contents")
public Page<ContentListResponseDto> findPage(RequestDto requestDto,
@PageableDefault(sort = "content_no", direction = Sort.Direction.DESC) Pageable pageable) {
return contentService.findPage(requestDto, pageable);
}
/**
* 컨텐츠 단건 조회
*
* @param contentNo 컨텐츠 번호
* @return ContentResponseDto 컨텐츠 상세 응답 DTO
*/
@GetMapping("/api/v1/contents/{contentNo}")
public ContentResponseDto findById(@PathVariable Integer contentNo) {
return contentService.findById(contentNo);
}
/**
* 컨텐츠 등록
*
* @param requestDto 컨텐츠 등록 요청 DTO
* @return ContentResponseDto 컨텐츠 상세 응답 DTO
*/
@PostMapping("/api/v1/contents")
public ContentResponseDto save(@RequestBody @Valid ContentSaveRequestDto requestDto) {
return contentService.save(requestDto);
}
/**
* 컨텐츠 수정
*
* @param contentNo 컨텐츠 번호
* @param requestDto 컨텐츠 수정 요청 DTO
* @return ContentResponseDto 컨텐츠 상세 응답 DTO
*/
@PutMapping("/api/v1/contents/{contentNo}")
public ContentResponseDto update(@PathVariable Integer contentNo, @RequestBody @Valid ContentUpdateRequestDto requestDto) {
return contentService.update(contentNo, requestDto);
}
/**
* 컨텐츠 삭제
*
* @param contentNo 컨텐츠 번호
*/
@DeleteMapping("/api/v1/contents/{contentNo}")
public void delete(@PathVariable Integer contentNo) {
contentService.delete(contentNo);
}
}

View File

@@ -0,0 +1,72 @@
package org.egovframe.cloud.portalservice.api.content.dto;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* org.egovframe.cloud.portalservice.api.content.dto.ContentListResponseDto
* <p>
* 컨텐츠 목록 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class ContentListResponseDto implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -1902534539945283321L;
/**
* 컨텐츠 번호
*/
private Integer contentNo;
/**
* 컨텐츠 명
*/
private String contentName;
/**
* 수정자
*/
private String lastModifiedBy;
/**
* 수정 일시
*/
private LocalDateTime modifiedDate;
/**
* 컨텐츠 목록 응답 DTO 생성자
*
* @param contentNo 컨텐츠 번호
* @param contentName 컨텐츠 명
* @param lastModifiedBy 수정자
* @param modifiedDate 수정 일시
*/
@QueryProjection
public ContentListResponseDto(Integer contentNo, String contentName, String lastModifiedBy, LocalDateTime modifiedDate) {
this.contentNo = contentNo;
this.contentName = contentName;
this.lastModifiedBy = lastModifiedBy;
this.modifiedDate = modifiedDate;
}
}

View File

@@ -0,0 +1,74 @@
package org.egovframe.cloud.portalservice.api.content.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.content.Content;
/**
* org.egovframe.cloud.portalservice.api.content.dto.ContentResponseDto
* <p>
* 컨텐츠 상세 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class ContentResponseDto {
/**
* 컨텐츠 번호
*/
private Integer contentNo;
/**
* 컨텐츠 명
*/
private String contentName;
/**
* 컨텐츠 비고
*/
private String contentRemark;
/**
* 컨텐츠 값
*/
private String contentValue;
/**
* 컨텐츠 엔티티를 생성자로 주입 받아서 컨텐츠 상세 응답 DTO 속성 값 세팅
*
* @param entity 컨텐츠 엔티티
*/
public ContentResponseDto(Content entity) {
this.contentNo = entity.getContentNo();
this.contentName = entity.getContentName();
this.contentRemark = entity.getContentRemark();
this.contentValue = entity.getContentValue();
}
/**
* 컨텐츠 상세 응답 DTO 속성 값으로 컨텐츠 엔티티 빌더를 사용하여 객체 생성
*
* @return Content 컨텐츠 엔티티
*/
public Content toEntity() {
return Content.builder()
.contentNo(contentNo)
.contentName(contentName)
.contentRemark(contentRemark)
.contentValue(contentValue)
.build();
}
}

View File

@@ -0,0 +1,58 @@
package org.egovframe.cloud.portalservice.api.content.dto;
import lombok.Getter;
import org.egovframe.cloud.portalservice.domain.content.Content;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.content.dto.ContentSaveRequestDto
* <p>
* 컨텐츠 등록 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@Getter
public class ContentSaveRequestDto {
/**
* 컨텐츠 명
*/
@NotBlank(message = "{content.content_name} {err.required}")
private String contentName;
/**
* 컨텐츠 비고
*/
private String contentRemark;
/**
* 컨텐츠 값
*/
@NotBlank(message = "{content.content_value} {err.required}")
private String contentValue;
/**
* 컨텐츠 등록 요청 DTO 속성 값으로 컨텐츠 엔티티 빌더를 사용하여 객체 생성
*
* @return Content 컨텐츠 엔티티
*/
public Content toEntity() {
return Content.builder()
.contentName(contentName)
.contentRemark(contentRemark)
.contentValue(contentValue)
.build();
}
}

View File

@@ -0,0 +1,44 @@
package org.egovframe.cloud.portalservice.api.content.dto;
import lombok.Getter;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.content.dto.ContentUpdateRequestDto
* <p>
* 컨텐츠 수정 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/08
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/08 jooho 최초 생성
* </pre>
*/
@Getter
public class ContentUpdateRequestDto {
/**
* 컨텐츠 명
*/
@NotBlank(message = "{content.content_name} {err.required}")
private String contentName;
/**
* 컨텐츠 비고
*/
private String contentRemark;
/**
* 컨텐츠 값
*/
@NotBlank(message = "{content.content_value} {err.required}")
private String contentValue;
}

View File

@@ -0,0 +1,128 @@
package org.egovframe.cloud.portalservice.api.menu;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.portalservice.api.menu.dto.*;
import org.egovframe.cloud.portalservice.domain.menu.SiteRepository;
import org.egovframe.cloud.portalservice.service.menu.MenuService;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.menu.MenuApiController
* <p>
* 메뉴관리 api controller 클래스
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Slf4j
@RequiredArgsConstructor // final이 선언된 모든 필드를 인자값으로 하는 생성자를 대신 생성하여, 빈을 생성자로 주입받게 한다.
@RestController
public class MenuApiController {
private final MenuService menuService;
private final SiteRepository siteRepository;
/**
* 사이트 목록 조회
*
* @return
*/
@GetMapping("/api/v1/sites")
public List<SiteResponseDto> findAllSites() {
return siteRepository.findAllByIsUseTrueOrderBySortSeq();
}
/**
* 관리자 메뉴 트리 목록 조회
*
* @param siteId
* @return
*/
@GetMapping("/api/v1/menus/{siteId}/tree")
public List<MenuTreeResponseDto> findTreeBySiteId(@PathVariable Long siteId) {
return menuService.findTreeBySiteId(siteId);
}
/**
* 메뉴 상세 정보 한건 조회
*
* @param menuId
* @return
*/
@GetMapping("/api/v1/menus/{menuId}")
public MenuResponseDto findById(@PathVariable Long menuId) {
return menuService.findById(menuId);
}
/**
* 트리 메뉴 한건 추가
*
* @param menuTreeRequestDto
* @return
*/
@PostMapping(value = "/api/v1/menus")
public MenuTreeResponseDto save(@RequestBody @Valid MenuTreeRequestDto menuTreeRequestDto) {
return menuService.save(menuTreeRequestDto);
}
/**
* 트리 드래그 앤드 드랍 저장
*
* @param siteId
* @param menuDnDRequestDtoList
* @return
*/
@PutMapping(value = "/api/v1/menus/{siteId}/tree")
public Long saveDnD(@PathVariable Long siteId, @RequestBody List<MenuDnDRequestDto> menuDnDRequestDtoList) {
return menuService.updateDnD(siteId, menuDnDRequestDtoList);
}
/**
* 트리에서 메뉴명 변경
*
* @param menuId
* @param name
* @return
*/
@PutMapping(value = "/api/v1/menus/{menuId}/{name}")
public MenuTreeResponseDto updateName(@PathVariable Long menuId, @PathVariable String name) {
return menuService.updateName(menuId, name);
}
/**
* 메뉴 상세 정보 변경
*
* @param menuId
* @param updateRequestDto
* @return
*/
@PutMapping(value = "/api/v1/menus/{menuId}")
public MenuResponseDto update(@PathVariable Long menuId, @RequestBody MenuUpdateRequestDto updateRequestDto) {
return menuService.update(menuId, updateRequestDto);
}
/**
* 메뉴 삭제
*
* @param menuId
*/
@DeleteMapping(value = "/api/v1/menus/{menuId}")
public void delete(@PathVariable Long menuId) {
menuService.delete(menuId);
}
}

View File

@@ -0,0 +1,72 @@
package org.egovframe.cloud.portalservice.api.menu;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleRequestDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuSideResponseDto;
import org.egovframe.cloud.portalservice.domain.user.User;
import org.egovframe.cloud.portalservice.service.menu.MenuRoleService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.menu.MenuRoleApiController
* <p>
* 권한별 메뉴관리 api controller 클래스
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/17
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/17 shinmj 최초 생성
* </pre>
*/
@Slf4j
@RequiredArgsConstructor // final이 선언된 모든 필드를 인자값으로 하는 생성자를 대신 생성하여, 빈을 생성자로 주입받게 한다.
@RestController
public class MenuRoleApiController {
private final MenuRoleService menuRoleService;
/**
* 권한별 메뉴관리 트리 목록 조회
*
* @param roleId
* @param siteId
* @return
*/
@GetMapping("/api/v1/menu-roles/{roleId}/{siteId}")
public List<MenuRoleResponseDto> findTree(@PathVariable String roleId, @PathVariable Long siteId, User user) {
return menuRoleService.fineTree(roleId.toUpperCase(), siteId);
}
/**
* 권한별 메뉴 저장
*
* @param menuRoleRequestDtoList
* @return
*/
@PostMapping("/api/v1/menu-roles")
public String save(@RequestBody List<MenuRoleRequestDto> menuRoleRequestDtoList) {
return menuRoleService.save(menuRoleRequestDtoList);
}
/**
* 로그인 후 사용자 권한에 따른 메뉴 조회
*
* @param siteId
* @return
*/
@GetMapping("/api/v1/menu-roles/{siteId}")
public List<MenuSideResponseDto> findMenus(@PathVariable Long siteId) {
return menuRoleService.findMenus(siteId);
}
}

View File

@@ -0,0 +1,53 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuDnDRequestDto
* <p>
* 메뉴관리 Tree Drag and Drop 저장 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuDnDRequestDto {
private Long menuId;
private String name;
private Integer sortSeq;
private Long parentId;
private Integer level;
private String icon;
private List<MenuDnDRequestDto> children = new ArrayList<>();
@Builder
public MenuDnDRequestDto(Long menuId, String name, Integer sortSeq, Long parentId, Integer level, String icon, List<MenuDnDRequestDto> children) {
this.menuId = menuId;
this.name = name;
this.sortSeq = sortSeq;
this.parentId = parentId;
this.level = level;
this.icon = icon;
this.children = children;
}
}

View File

@@ -0,0 +1,59 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Menu;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuResponseDto
* <p>
* 메뉴관리 상세 정보 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuResponseDto {
private Long menuId;
private String menuKorName;
private String menuEngName;
private String menuType;
private Integer connectId;
private String connectName;
private String urlPath;
private Boolean isUse;
private Boolean isShow;
private Boolean isBlank;
private String subName;
private String description;
private String icon;
@Builder
public MenuResponseDto(Menu entity) {
this.menuId = entity.getId();
this.menuKorName = entity.getMenuKorName();
this.menuEngName = entity.getMenuEngName();
this.menuType = entity.getMenuType();
this.connectId = entity.getConnectId();
this.urlPath = entity.getUrlPath();
this.isUse = entity.getIsUse();
this.isShow = entity.getIsShow();
this.isBlank = entity.getIsBlank();
this.subName = entity.getSubName();
this.description = entity.getDescription();
this.icon = entity.getIcon();
}
}

View File

@@ -0,0 +1,58 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleRequestDto
* <p>
* 권한별 메뉴관리 저장 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/13
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/13 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuRoleRequestDto {
private Long menuRoleId;
private String roleId;
private Boolean isChecked;
private Long id;
private String korName;
private String engName;
private Long parentId;
private Integer sortSeq;
private String icon;
private Integer level;
private List<MenuRoleRequestDto> children;
@Builder
public MenuRoleRequestDto(Long menuRoleId, String roleId, Boolean isChecked, Long id, String korName, String engName, Long parentId, Integer sortSeq, String icon, Integer level, List<MenuRoleRequestDto> children) {
this.menuRoleId = menuRoleId;
this.roleId = roleId;
this.isChecked = isChecked;
this.id = id;
this.korName = korName;
this.engName = engName;
this.parentId = parentId;
this.sortSeq = sortSeq;
this.icon = icon;
this.level = level;
this.children = children;
}
}

View File

@@ -0,0 +1,82 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Menu;
import org.egovframe.cloud.portalservice.domain.menu.MenuRole;
import java.util.List;
import java.util.stream.Collectors;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleResponseDto
* <p>
* 권한별 메뉴관리 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/13
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/13 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuRoleResponseDto {
private Long menuRoleId;
private String roleId;
private Boolean isChecked;
private Long id;
private String korName;
private String engName;
private Long parentId;
private Integer sortSeq;
private String icon;
private Integer level;
@ToString.Exclude
private List<MenuRoleResponseDto> children;
/**
* 생성자
* querydsl 사용시 Menu Entity로 생성
* roleId에 해당하는 권한별 메뉴 데이터만 조회
*
* @param menu
* @param roleId
*/
public MenuRoleResponseDto (Menu menu, String roleId) {
MenuRole menuRole = menu.getMenuRole(roleId);
if (menuRole == null) {
this.isChecked = false;
this.roleId = roleId;
}else {
this.menuRoleId = menuRole.getId();
this.roleId = menuRole.getRoleId();
this.isChecked = true;
}
this.id = menu.getId();
this.korName = menu.getMenuKorName();
this.engName = menu.getMenuEngName();
if (menu.getParent() != null) {
this.parentId = menu.getParent().getId();
}
this.sortSeq = menu.getSortSeq();
this.icon = menu.getIcon();
this.level = menu.getLevel();
this.children = menu.getChildren().stream()
.map(children -> new MenuRoleResponseDto(children, roleId))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,82 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Menu;
import java.util.List;
import java.util.stream.Collectors;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuSideResponseDto
* <p>
* 로그인 후 사용자 권한별 메뉴 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/13
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/13 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuSideResponseDto {
private Long id;
private String korName;
private String engName;
private Long parentId;
private Integer sortSeq;
private String icon;
private Integer level;
private String urlPath;
private Integer connectId;
private String menuType;
private Boolean isShow;
@ToString.Exclude
private List<MenuSideResponseDto> children;
/**
* 생성자
* 계층구조를 만들기 위해 querydsl에서 사용
*
* @param menu
*/
public MenuSideResponseDto (Menu menu, String roleId) {
this.id = menu.getId();
this.korName = menu.getMenuKorName();
this.engName = menu.getMenuEngName();
if (menu.getParent() != null) {
this.parentId = menu.getParent().getId();
}
this.sortSeq = menu.getSortSeq();
this.icon = menu.getIcon();
this.level = menu.getLevel();
this.menuType = menu.getMenuType();
this.connectId = menu.getConnectId();
this.urlPath = menu.getUrlPath();
this.isShow = menu.getIsShow();
this.children = menu.getChildren().stream()
.filter(children -> children.getIsUse())
.filter(children -> children.getMenuRole(roleId) != null)
.map(children -> new MenuSideResponseDto(children, roleId))
.collect(Collectors.toList());
}
/**
* 메뉴유형이 게시판이나 컨텐츠인 경우 urlPath 지정
*
* @param urlPath
*/
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
}

View File

@@ -0,0 +1,51 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Menu;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuTreeRequestDto
* <p>
* 메뉴관리 tree 추가 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuTreeRequestDto {
private Long siteId;
private String name;
private Integer sortSeq;
private Long parentId;
private Integer level;
private Boolean isShow;
private Boolean isUse;
@Builder
public MenuTreeRequestDto(Long siteId, String name, Integer sortSeq, Long parentId, Integer level, Boolean isShow, Boolean isUse) {
this.siteId = siteId;
this.name = name;
this.sortSeq = sortSeq;
this.parentId = parentId;
this.level = level;
this.isShow = isShow;
this.isUse = isUse;
}
}

View File

@@ -0,0 +1,57 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Menu;
import java.util.List;
import java.util.stream.Collectors;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuTreeResponseDto
* <p>
* 메뉴관리 tree 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuTreeResponseDto {
private Long menuId;
private String name;
private Long parentId;
private Integer sortSeq;
private String icon;
@ToString.Exclude
private List<MenuTreeResponseDto> children;
private Integer level;
@Builder
public MenuTreeResponseDto(Menu entity) {
this.menuId = entity.getId();
this.name = entity.getMenuKorName();
if (entity.getParent() != null) {
this.parentId = entity.getParent().getId();
}
this.sortSeq = entity.getSortSeq();
this.icon = entity.getIcon();
this.level = entity.getLevel();
this.children = entity.getChildren().stream()
.map(children -> new MenuTreeResponseDto(children))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,61 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.MenuUpdateRequestDto
* <p>
* 메뉴관리 상세정보 요청 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class MenuUpdateRequestDto {
@NotBlank(message = "{menu.name}{valid.required}")
private String menuKorName;
@NotBlank(message = "{menu.eng_name}{valid.required}")
private String menuEngName;
private String menuType;
private String menuTypeName;
private Integer connectId;
private String urlPath;
private Boolean isUse;
private Boolean isShow;
private Boolean isBlank;
private String subName;
private String description;
private String icon;
@Builder
public MenuUpdateRequestDto(String menuKorName, String menuEngName, String menuType, String menuTypeName, Integer connectId, String urlPath, Boolean isUse, Boolean isShow, Boolean isBlank, String subName, String description, String icon) {
this.menuKorName = menuKorName;
this.menuEngName = menuEngName;
this.menuType = menuType;
this.menuTypeName = menuTypeName;
this.connectId = connectId;
this.urlPath = urlPath;
this.isUse = isUse;
this.isShow = isShow;
this.isBlank = isBlank;
this.subName = subName;
this.description = description;
this.icon = icon;
}
}

View File

@@ -0,0 +1,40 @@
package org.egovframe.cloud.portalservice.api.menu.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.menu.Site;
/**
* org.egovframe.cloud.portalservice.api.menu.dto.SiteResponseDto
* <p>
* 메뉴관리 사이트 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class SiteResponseDto {
private Long id;
private String name;
private Boolean isUse;
@Builder
public SiteResponseDto(Site entity) {
this.id = entity.getId();
this.name = entity.getName();
this.isUse = entity.getIsUse();
}
}

View File

@@ -0,0 +1,74 @@
package org.egovframe.cloud.portalservice.api.message;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.portalservice.api.message.dto.MessageListResponseDto;
import org.egovframe.cloud.portalservice.config.MessageSourceFiles;
import org.egovframe.cloud.portalservice.domain.message.MessageRepository;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* org.egovframe.cloud.portalservice.api.message.MessageApiController
* <p>
* Message 요청을 처리하는 REST API Controller
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor // final이 선언된 모든 필드를 인자값으로 하는 생성자를 대신 생성하여, 빈을 생성자로 주입받게 한다.
@RestController
public class MessageApiController {
private final MessageRepository messageRepository;
private final MessageSource messageSource;
private final MessageSourceFiles messageSourceFiles;
/**
* Message 목록 조회
*
* @param lang ko/en
* @return
* @deprecated Map 형태 반환을 기본으로 한다. 이 API는 사용하지 않는다.
*/
@GetMapping("/api/v1/messages/{lang}/list-type")
public List<MessageListResponseDto> findAllMessages(@PathVariable String lang) {
return messageRepository.findAllMessages(lang);
}
/**
* Message 목록 조회하여 Map 형태로 변환하여 반환한다
*
* @param lang ko/en
* @return
*/
@GetMapping("/api/v1/messages/{lang}")
public Map<String, String> findAllMessagesMap(@PathVariable String lang) {
return messageRepository.findAllMessagesMap(lang);
}
@GetMapping("/api/v1/messages/{code}/{lang}")
public String getMessage(@PathVariable String code, @PathVariable String lang) {
Locale locale = "en".equals(lang)? Locale.ENGLISH : Locale.KOREAN;
return messageSource.getMessage(code, null, locale);
}
@GetMapping("/api/v1/messages/refresh")
public int refresh() {
return messageSourceFiles.create();
}
}

View File

@@ -0,0 +1,30 @@
package org.egovframe.cloud.portalservice.api.message.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
/**
* org.egovframe.cloud.portalservice.api.message.dto.MessageListResponseDto
* <p>
* Message 목록 조회 응답 dto
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class MessageListResponseDto {
private String messageId;
private String messageName;
}

View File

@@ -0,0 +1,119 @@
package org.egovframe.cloud.portalservice.api.policy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.policy.dto.PolicyResponseDto;
import org.egovframe.cloud.portalservice.api.policy.dto.PolicySaveRequestDto;
import org.egovframe.cloud.portalservice.api.policy.dto.PolicyUpdateRequestDto;
import org.egovframe.cloud.portalservice.service.policy.PolicyService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
/**
* org.egovframe.cloud.portalservice.api.policy.PolicyApiController
* <p>
* 이용약관/개인정보수집동의(Policy) API class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/06
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/06 shinmj 최초 생성
* </pre>
*/
@Slf4j
@RequiredArgsConstructor
@RestController
public class PolicyApiController {
private final PolicyService policyService;
/**
* 목록 조회
*
* @param requestDto
* @param pageable
* @return
*/
@GetMapping("/api/v1/policies")
public Page<PolicyResponseDto> search(RequestDto requestDto, Pageable pageable) {
return policyService.search(requestDto, pageable);
}
/**
* 단건 조회
*
* @param id
* @return
*/
@GetMapping("/api/v1/policies/{id}")
public PolicyResponseDto findById(@PathVariable Long id) {
return policyService.findById(id);
}
/**
* 회원가입 시 가장 최근등록 된 자료 단건 조회
*
* @param type
* @return
*/
@GetMapping("/api/v1/policies/latest/{type}")
public PolicyResponseDto searchOne(@PathVariable String type) {
return policyService.searchOne(type);
}
/**
* 등록
*
* @param saveRequestDto
* @return
*/
@PostMapping("/api/v1/policies")
public Long save(@RequestBody PolicySaveRequestDto saveRequestDto) {
System.out.println(saveRequestDto.toString());
return policyService.save(saveRequestDto);
}
/**
* 수정
*
* @param id
* @param updateRequestDto
* @return
*/
@PutMapping("/api/v1/policies/{id}")
public Long update(@PathVariable Long id, @RequestBody PolicyUpdateRequestDto updateRequestDto) {
return policyService.update(id, updateRequestDto);
}
/**
* 사용여부 toggle
*
* @param id
* @param isUse
* @return
*/
@PutMapping("/api/v1/policies/{id}/{isUse}")
public Long updateIsUse(@PathVariable Long id, @PathVariable boolean isUse) {
return policyService.updateIsUse(id, isUse);
}
/**
* 삭제
*
* @param id
*/
@DeleteMapping("/api/v1/policies/{id}")
public void delete(@PathVariable Long id) {
policyService.delete(id);
}
}

View File

@@ -0,0 +1,50 @@
package org.egovframe.cloud.portalservice.api.policy.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.domain.policy.Policy;
import java.time.ZonedDateTime;
/**
* org.egovframe.cloud.portalservice.api.policy.dto.PolicyResponseDto
* <p>
* 이용약관/개인정보수집동의(Policy) 응답 dto
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/06
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/06 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class PolicyResponseDto {
private Long id;
private String type;
private String title;
private Boolean isUse;
private ZonedDateTime regDate;
private String contents;
@Builder
public PolicyResponseDto(Policy policy){
this.id = policy.getId();
this.type = policy.getType();
this.title = policy.getTitle();
this.isUse = policy.getIsUse();
this.regDate = policy.getRegDate();
this.contents = policy.getContents();
}
}

View File

@@ -0,0 +1,62 @@
package org.egovframe.cloud.portalservice.api.policy.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.policy.Policy;
import javax.validation.constraints.NotBlank;
import java.time.ZonedDateTime;
/**
* org.egovframe.cloud.portalservice.api.policy.dto.PolicySaveRequestDto
* <p>
* 이용약관/개인정보수집동의(Policy) 등록 시 요청 dto
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/06
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/06 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class PolicySaveRequestDto {
@NotBlank(message = "{common.type}{valid.required}")
private String type;
@NotBlank(message = "{policy.title}{valid.required}")
private String title;
private Boolean isUse;
private ZonedDateTime regDate;
private String contents;
@Builder
public PolicySaveRequestDto(String type, String title, Boolean isUse, ZonedDateTime regDate, String contents){
this.type = type;
this.title = title;
this.isUse = isUse;
this.regDate = regDate;
this.contents = contents;
}
/**
* 저장 요청 dto -> 이용약관 entity
*
* @return
*/
public Policy toEntity(){
return Policy.builder()
.type(this.type)
.title(this.title)
.isUse(this.isUse)
.regDate(this.regDate)
.contents(this.contents)
.build();
}
}

View File

@@ -0,0 +1,38 @@
package org.egovframe.cloud.portalservice.api.policy.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.policy.dto.PolicyUpdateRequestDto
* <p>
* 이용약관/개인정보수집동의(Policy) 수정 시 요청 dto
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/06
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/06 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class PolicyUpdateRequestDto {
private String title;
private Boolean isUse;
private String contents;
@Builder
public PolicyUpdateRequestDto(String title, Boolean isUse, String contents){
this.title = title;
this.isUse = isUse;
this.contents = contents;
}
}

View File

@@ -0,0 +1,132 @@
package org.egovframe.cloud.portalservice.api.privacy;
import java.util.List;
import javax.validation.Valid;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyListResponseDto;
import org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyResponseDto;
import org.egovframe.cloud.portalservice.api.privacy.dto.PrivacySaveRequestDto;
import org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyUpdateRequestDto;
import org.egovframe.cloud.portalservice.service.privacy.PrivacyService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
/**
* org.egovframe.cloud.portalservice.api.privacy.PrivacyApiController
* <p>
* 개인정보처리방침 Rest API 컨트롤러 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@RestController
public class PrivacyApiController {
/**
* 개인정보처리방침 서비스
*/
private final PrivacyService privacyService;
/**
* 개인정보처리방침 페이지 목록 조회
*
* @param requestDto 요청 DTO
* @param pageable 페이지 정보
* @return Page<PrivacyListResponseDto> 페이지 개인정보처리방침 목록 응답 DTO
*/
@GetMapping("/api/v1/privacies")
public Page<PrivacyListResponseDto> findPage(RequestDto requestDto,
@PageableDefault(sort = "privacy_no", direction = Sort.Direction.DESC) Pageable pageable) {
return privacyService.findPage(requestDto, pageable);
}
/**
* 개인정보처리방침 사용중인 내림차순 전체 목록 조회
*
* @return List<PrivacyResponseDto> 개인정보처리방침 상세 응답 DTO List
*/
@GetMapping("/api/v1/privacies/all/use")
public List<PrivacyResponseDto> findAllByUse() {
return privacyService.findAllByUseAt(true);
}
/**
* 개인정보처리방침 단건 조회
*
* @param privacyNo 개인정보처리방침 번호
* @return PrivacyResponseDto 개인정보처리방침 상세 응답 DTO
*/
@GetMapping("/api/v1/privacies/{privacyNo}")
public PrivacyResponseDto findById(@PathVariable Integer privacyNo) {
return privacyService.findById(privacyNo);
}
/**
* 개인정보처리방침 등록
*
* @param requestDto 개인정보처리방침 등록 요청 DTO
* @return PrivacyResponseDto 개인정보처리방침 상세 응답 DTO
*/
@PostMapping("/api/v1/privacies")
public PrivacyResponseDto save(@RequestBody @Valid PrivacySaveRequestDto requestDto) {
return privacyService.save(requestDto);
}
/**
* 개인정보처리방침 수정
*
* @param privacyNo 개인정보처리방침 번호
* @param requestDto 개인정보처리방침 수정 요청 DTO
* @return PrivacyResponseDto 개인정보처리방침 상세 응답 DTO
*/
@PutMapping("/api/v1/privacies/{privacyNo}")
public PrivacyResponseDto update(@PathVariable Integer privacyNo, @RequestBody @Valid PrivacyUpdateRequestDto requestDto) {
return privacyService.update(privacyNo, requestDto);
}
/**
* 개인정보처리방침 사용 여부 수정
*
* @param privacyNo 개인정보처리방침 번호
* @param useAt 사용 여부
* @return PrivacyResponseDto 개인정보처리방침 상세 응답 DTO
*/
@PutMapping("/api/v1/privacies/{privacyNo}/{useAt}")
public PrivacyResponseDto updateUseAt(@PathVariable Integer privacyNo, @PathVariable Boolean useAt) {
return privacyService.updateUseAt(privacyNo, useAt);
}
/**
* 개인정보처리방침 삭제
*
* @param privacyNo 개인정보처리방침 번호
*/
@DeleteMapping("/api/v1/privacies/{privacyNo}")
public void delete(@PathVariable Integer privacyNo) {
privacyService.delete(privacyNo);
}
}

View File

@@ -0,0 +1,72 @@
package org.egovframe.cloud.portalservice.api.privacy.dto;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyListResponseDto
* <p>
* 개인정보처리방침 목록 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/23 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class PrivacyListResponseDto implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -6649931248096772439L;
/**
* 개인정보처리방침 번호
*/
private Integer privacyNo;
/**
* 개인정보처리방침 제목
*/
private String privacyTitle;
/**
* 사용 여부
*/
private Boolean useAt;
/**
* 생성 일시
*/
private LocalDateTime createdDate;
/**
* 개인정보처리방침 목록 응답 DTO 생성자
*
* @param privacyNo 개인정보처리방침 번호
* @param privacyTitle 개인정보처리방침 제목
* @param useAt 사용 여부
* @param createdDate 생성 일시
*/
@QueryProjection
public PrivacyListResponseDto(Integer privacyNo, String privacyTitle, Boolean useAt, LocalDateTime createdDate) {
this.privacyNo = privacyNo;
this.privacyTitle = privacyTitle;
this.useAt = useAt;
this.createdDate = createdDate;
}
}

View File

@@ -0,0 +1,91 @@
package org.egovframe.cloud.portalservice.api.privacy.dto;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.privacy.Privacy;
/**
* org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyResponseDto
* <p>
* 개인정보처리방침 상세 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/23 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class PrivacyResponseDto {
/**
* 개인정보처리방침 번호
*/
private Integer privacyNo;
/**
* 개인정보처리방침 제목
*/
private String privacyTitle;
/**
* 개인정보처리방침 내용
*/
private String privacyContent;
/**
* 사용 여부
*/
private Boolean useAt;
/**
* 개인정보처리방침 목록 응답 DTO 생성자
*
* @param privacyNo 개인정보처리방침 번호
* @param privacyTitle 개인정보처리방침 제목
* @param privacyContent 개인정보처리방침 내용
* @param useAt 사용 여부
*/
@QueryProjection
public PrivacyResponseDto(Integer privacyNo, String privacyTitle, String privacyContent, Boolean useAt) {
this.privacyNo = privacyNo;
this.privacyTitle = privacyTitle;
this.privacyContent = privacyContent;
this.useAt = useAt;
}
/**
* 개인정보처리방침 엔티티를 생성자로 주입 받아서 개인정보처리방침 상세 응답 DTO 속성 값 세팅
*
* @param entity 개인정보처리방침 엔티티
*/
public PrivacyResponseDto(Privacy entity) {
this.privacyNo = entity.getPrivacyNo();
this.privacyTitle = entity.getPrivacyTitle();
this.privacyContent = entity.getPrivacyContent();
this.useAt = entity.getUseAt();
}
/**
* 개인정보처리방침 상세 응답 DTO 속성 값으로 개인정보처리방침 엔티티 빌더를 사용하여 객체 생성
*
* @return Privacy 개인정보처리방침 엔티티
*/
public Privacy toEntity() {
return Privacy.builder()
.privacyNo(privacyNo)
.privacyTitle(privacyTitle)
.privacyContent(privacyContent)
.useAt(useAt)
.build();
}
}

View File

@@ -0,0 +1,60 @@
package org.egovframe.cloud.portalservice.api.privacy.dto;
import lombok.Getter;
import org.egovframe.cloud.portalservice.domain.privacy.Privacy;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* org.egovframe.cloud.portalservice.api.privacy.dto.PrivacySaveRequestDto
* <p>
* 개인정보처리방침 등록 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/23 jooho 최초 생성
* </pre>
*/
@Getter
public class PrivacySaveRequestDto {
/**
* 개인정보처리방침 제목
*/
@NotBlank(message = "{privacy.privacy_title} {err.required}")
private String privacyTitle;
/**
* 개인정보처리방침 내용
*/
@NotBlank(message = "{privacy.privacy_content} {err.required}")
private String privacyContent;
/**
* 사용 여부
*/
@NotNull(message = "{common.use_at} {err.required}")
private Boolean useAt;
/**
* 개인정보처리방침 등록 요청 DTO 속성 값으로 개인정보처리방침 엔티티 빌더를 사용하여 객체 생성
*
* @return Privacy 개인정보처리방침 엔티티
*/
public Privacy toEntity() {
return Privacy.builder()
.privacyTitle(privacyTitle)
.privacyContent(privacyContent)
.useAt(useAt)
.build();
}
}

View File

@@ -0,0 +1,46 @@
package org.egovframe.cloud.portalservice.api.privacy.dto;
import lombok.Getter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* org.egovframe.cloud.portalservice.api.privacy.dto.PrivacyUpdateRequestDto
* <p>
* 개인정보처리방침 수정 요청 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/08
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/08 jooho 최초 생성
* </pre>
*/
@Getter
public class PrivacyUpdateRequestDto {
/**
* 개인정보처리방침 제목
*/
@NotBlank(message = "{privacy.privacy_title} {err.required}")
private String privacyTitle;
/**
* 개인정보처리방침 내용
*/
@NotBlank(message = "{privacy.privacy_content} {err.required}")
private String privacyContent;
/**
* 사용 여부
*/
@NotNull(message = "{common.use_at} {err.required}")
private Boolean useAt;
}

View File

@@ -0,0 +1,65 @@
package org.egovframe.cloud.portalservice.api.statistics;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.portalservice.api.statistics.dto.StatisticsResponseDto;
import org.egovframe.cloud.portalservice.api.statistics.dto.StatisticsYMRequestDto;
import org.egovframe.cloud.portalservice.service.statistics.StatisticsService;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.api.statistics.StatisticsApiController
* <p>
* 통계 api controller class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/09/07
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/09/07 shinmj 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@RestController
public class StatisticsApiController {
private final StatisticsService statisticsService;
/**
* 접속 통계 월별
*
* @param siteId
* @return
*/
@GetMapping("/api/v1/statistics/monthly/{siteId}")
public List<StatisticsResponseDto> findMonthlyBySiteId(@PathVariable Long siteId) {
return statisticsService.findMonthlyBySiteId(siteId);
}
/**
* 접속 통계 일별
*
* @param siteId
* @return
*/
@GetMapping("/api/v1/statistics/daily/{siteId}")
public List<StatisticsResponseDto> findDailyBySiteId(@PathVariable Long siteId, StatisticsYMRequestDto requestDto) {
return statisticsService.findDailyBySiteId(siteId, requestDto);
}
/**
* 접속통계 등록
*
* @param statisticsId
* @param request
*/
@PostMapping("/api/v1/statistics/{statisticsId}")
public void save(@PathVariable String statisticsId, HttpServletRequest request) {
statisticsService.save(request, statisticsId);
}
}

View File

@@ -0,0 +1,57 @@
package org.egovframe.cloud.portalservice.api.statistics.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* org.egovframe.cloud.portalservice.api.statistics.dto.StatisticsResponseDto
* <p>
* 통계 차트 응답 dto class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/09/07
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/09/07 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
public class StatisticsResponseDto {
private Integer year;
private Integer month;
private Integer day;
private String x;
private Long y;
@Builder
public StatisticsResponseDto(Integer year, Integer month, Integer day, Integer x, Long y) {
this.year = year;
this.month = month;
this.day = day;
this.x = convertLabel(x);
this.y = y;
}
/**
* 일/월 에 대한 라벨 설정
* 01,02....11...31
*
* @param x
* @return
*/
private String convertLabel(Integer x) {
if (x < 10) {
return "0"+x;
}
return ""+x;
}
}

View File

@@ -0,0 +1,20 @@
package org.egovframe.cloud.portalservice.api.statistics.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Getter
@NoArgsConstructor
@ToString
public class StatisticsYMRequestDto {
private Integer year;
private Integer month;
@Builder
public StatisticsYMRequestDto(Integer year, Integer month) {
this.year = year;
this.month = month;
}
}

View File

@@ -0,0 +1,36 @@
package org.egovframe.cloud.portalservice.client;
import org.egovframe.cloud.portalservice.client.dto.BoardResponseDto;
import org.egovframe.cloud.portalservice.config.CustomFeignConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* org.egovframe.cloud.portalservice.client.BoardServiceClient
* <p>
* 게시판 서비스와 통신하는 feign client interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/19
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/19 shinmj 최초 생성
* </pre>
*/
@FeignClient(value = "board-service", configuration = CustomFeignConfiguration.class)
public interface BoardServiceClient {
/**
* 게시판 한건 조회
*
* @param boardNo
* @return
*/
@GetMapping("/api/v1/boards/{boardNo}")
BoardResponseDto findById(@PathVariable("boardNo") Integer boardNo);
}

View File

@@ -0,0 +1,51 @@
package org.egovframe.cloud.portalservice.client.decoder;
import feign.Response;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.exception.BusinessException;
import org.egovframe.cloud.common.exception.BusinessMessageException;
import org.egovframe.cloud.common.exception.dto.ErrorCode;
/**
* org.egovframe.cloud.portalservice.client.decoder.CustomErrorDecoder
* <p>
* feign client custom 에러 핸들링 클래스
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/23 shinmj 최초 생성
* </pre>
*/
@Slf4j
public class CustomErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
log.info("%s 요청이 성공하지 못했습니다. status : %s, body : %s",
methodKey, response.status(), response.body());
switch (response.status()) {
case 400:
return new BusinessMessageException(response.body().toString());
case 401:
return new BusinessException(ErrorCode.UNAUTHORIZED);
case 403:
return new BusinessException(ErrorCode.JWT_EXPIRED);
case 404:
return new BusinessException(ErrorCode.NOT_FOUND);
case 405:
return new BusinessException(ErrorCode.METHOD_NOT_ALLOWED);
case 422:
return new BusinessException(ErrorCode.UNPROCESSABLE_ENTITY);
default:
return new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -0,0 +1,94 @@
package org.egovframe.cloud.portalservice.client.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* org.egovframe.cloud.boardservice.api.board.dto.BoardResponseDto
* <p>
* 게시판 상세 응답 DTO 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/26
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/26 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
public class BoardResponseDto implements Serializable {
/**
* SerialVersionUID
*/
private static final long serialVersionUID = -7139346671431363426L;
/**
* 게시판 번호
*/
private Integer boardNo;
/**
* 게시판 제목
*/
private String boardName;
/**
* 스킨 유형 코드
*/
private String skinTypeCode;
/**
* 제목 표시 길이
*/
private Integer titleDisplayLength;
/**
* 게시물 표시 수
*/
private Integer postDisplayCount;
/**
* 페이지 표시 수
*/
private Integer pageDisplayCount;
/**
* 표시 신규 수
*/
private Integer newDisplayDayCount;
/**
* 에디터 사용 여부
*/
private Boolean editorUseAt;
/**
* 댓글 사용 여부
*/
private Boolean commentUseAt;
/**
* 업로드 사용 여부
*/
private Boolean uploadUseAt;
/**
* 업로드 제한 수
*/
private Integer uploadLimitCount;
/**
* 업로드 제한 크기
*/
private Integer uploadLimitSize;
}

View File

@@ -0,0 +1,58 @@
package org.egovframe.cloud.portalservice.config;
import feign.Logger;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import org.egovframe.cloud.portalservice.client.decoder.CustomErrorDecoder;
import org.springframework.context.annotation.Bean;
/**
* org.egovframe.cloud.portalservice.config.CustomFeignConfiguration
* <p>
* feign client custom 설정 클래스
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/23 shinmj 최초 생성
* </pre>
*/
public class CustomFeignConfiguration {
/**
* log level 설정
*
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
/**
* 에러 핸들링
*
* @return
*/
@Bean
public ErrorDecoder errorDecoder() {
return new CustomErrorDecoder();
}
/**
* retryer 설정
*
* @return
*/
@Bean
public Retryer retryer() {
return new Retryer.Default();
}
}

View File

@@ -0,0 +1,30 @@
package org.egovframe.cloud.portalservice.config;
import java.util.function.Consumer;
import org.egovframe.cloud.common.dto.AttachmentEntityMessage;
import org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentUploadRequestDto;
import org.egovframe.cloud.portalservice.service.attachment.AttachmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
public class EventStreamConfig {
@Autowired
private AttachmentService attachmentService;
@Bean
public Consumer<AttachmentEntityMessage> attachmentEntity() {
return attachmentEntityMessage -> attachmentService.updateEntity(
attachmentEntityMessage.getAttachmentCode(),
AttachmentUploadRequestDto.builder()
.entityName(attachmentEntityMessage.getEntityName())
.entityId(attachmentEntityMessage.getEntityId())
.build());
}
}

View File

@@ -0,0 +1,120 @@
package org.egovframe.cloud.portalservice.config;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.portalservice.domain.message.Message;
import org.egovframe.cloud.portalservice.domain.message.MessageRepository;
import org.egovframe.cloud.portalservice.utils.FileStorageUtils;
import org.egovframe.cloud.portalservice.utils.FtpClientDto;
import org.egovframe.cloud.portalservice.utils.StorageUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* org.egovframe.cloud.portalservice.config.MessageSourceFileCreate
* <p>
* 서비스 기동시 호출되어 messages/messages{lang}.properties 를 jar 실행되는 위치에 생성한다.
* 각 서비스에서 해당 파일을 통해 다국어를 지원하도록 한다.
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/08/09
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/09 jaeyeolkim 최초 생성
* </pre>
*/
@Slf4j
@RefreshScope
@Component
public class MessageSourceFiles {
private final MessageRepository messageRepository;
private final Environment environment;
private final StorageUtils storageUtils;
public MessageSourceFiles(MessageRepository messageRepository, Environment environment, StorageUtils storageUtils) {
this.messageRepository = messageRepository;
this.environment = environment;
this.storageUtils = storageUtils;
}
@PostConstruct
public int create() {
// db 에서 messages 를 조회한다.
List<Message> messages = messageRepository.findAll();
log.info("messages size = {}", messages.size());
if (messages.size() == 0) {
return 0;
}
// 기본 properties 파일과 언어별 properties 파일을 생성한다.
String[] langs = new String[]{"", "_ko", "_en"};
List<File> files = new ArrayList<>();
// 메시지 폴더 경로
final String fileMessagesDirectory = StringUtils.cleanPath(environment.getProperty("file.directory") + "/messages");
try {
Files.createDirectory(Paths.get(fileMessagesDirectory).toAbsolutePath().normalize());
} catch (FileAlreadyExistsException e) {
log.info("메시지 폴더 경로에 파일이나 디렉토리가 이미 존재, {}", e.getMessage());
} catch (IOException e) {
log.error("메시지 폴더 생성 오류", e);
}
for (String lang : langs) {
Properties prop = new Properties();
// Properties 에 조회한 messages set
if ("_en".equals(lang)) {
for (Message message : messages) {
String name = StringUtils.hasLength(message.getMessageEnName()) ? message.getMessageEnName() : message.getMessageKoName();
prop.setProperty(message.getMessageId(), name);
}
} else {
for (Message message : messages) {
prop.setProperty(message.getMessageId(), message.getMessageKoName());
}
}
File propFile = new File(StringUtils.cleanPath(fileMessagesDirectory + "/messages" + lang + ".properties"));
log.info("messages properties path={}", propFile.getPath());
propFile.setReadable(true);
propFile.setWritable(true, true);
try (FileOutputStream out = new FileOutputStream(propFile)) {
prop.store(out, "messages");
} catch (IOException e) {
log.error("Messages FileOutputStream IOException = {}, {}", e.getMessage(), e.getCause());
}
// files
files.add(propFile);
}
String ftpEnabled = environment.getProperty("ftp.enabled");
// files 있는 경우 ftp 서버에 올린다.
if ((StringUtils.hasLength(ftpEnabled) || "true".equals(ftpEnabled)) && !files.isEmpty()) {
storageUtils.storeFiles(files, "messages");
}
return messages.size();
}
}

View File

@@ -0,0 +1,49 @@
package org.egovframe.cloud.portalservice.config;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
/**
* org.egovframe.cloud.portalservice.config.Resilience4JConfig
* <p>
* Resilience4J Configuration
* 기본 설정값으로 운영되어도 무방하다. 이 클래스는 필수는 아니다.
* retry 기본값은 최대 3회이고, fallback 이 없는 경우에만 동작하므로 설정하지 않았다.
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/08/31
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/31 jaeyeolkim 최초 생성
* </pre>
*/
@Configuration
public class Resilience4JConfig {
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> resilience4JCircuitBreakerFactoryCustomizer() {
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // Circuit 열지 말지 결정하는 실패 threshold 퍼센테이지
.waitDurationInOpenState(Duration.ofSeconds(5)) // (half closed 전에) circuitBreaker가 open 되기 전에 기다리는 기간
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) // circuit breaker count 기반 처리
.slidingWindowSize(10) // 통계 대상 건수 -> N건의 요청중..
.build();
return circuitBreakerFactory -> circuitBreakerFactory.configureDefault(
id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(circuitBreakerConfig)
.build()
);
}
}

View File

@@ -0,0 +1,65 @@
package org.egovframe.cloud.portalservice.config;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.servlet.config.AuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
/**
* org.egovframe.cloud.portalservice.config.SecurityConfig
* <p>
* Spring Security Config 클래스
* AuthenticationFilter 를 추가하고 토큰으로 setAuthentication 인증처리를 한다
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/06/30
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/06/30 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor
@EnableWebSecurity // Spring Security 설정들을 활성화시켜 준다
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${token.secret}")
private String TOKEN_SECRET;
/**
* 스프링 시큐리티 설정
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 토큰 사용하기 때문에 세션은 비활성화
.and()
.addFilter(getAuthenticationFilter());
}
/**
* 토큰에 담긴 정보로 Authentication 정보를 설정하여 jpa audit 처리에 사용된다.
* 이 처리를 하지 않으면 AnonymousAuthenticationToken 으로 처리된다.
*
* @return
* @throws Exception
*/
private AuthenticationFilter getAuthenticationFilter() throws Exception {
return new AuthenticationFilter(authenticationManager(), TOKEN_SECRET);
}
}

View File

@@ -0,0 +1,45 @@
package org.egovframe.cloud.portalservice.config;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.util.MessageUtil;
import org.egovframe.cloud.portalservice.utils.FileStorageUtils;
import org.egovframe.cloud.portalservice.utils.FtpStorageUtils;
import org.egovframe.cloud.portalservice.utils.StorageUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
/**
* org.egovframe.cloud.portalservice.config.StorageConfig
* <p>
* StorageConfig Config 클래스
* ftp 서버 사용 여부에 따라 StorageUtils 에 주입하는 빈이 달라진다.
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/09/08
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/09/08 jaeyeolkim 최초 생성
* </pre>
*/
@Slf4j
@Configuration
public class StorageConfig {
@Bean
public StorageUtils storageUtils(Environment environment, MessageUtil messageUtil) {
String ftpEnabled = environment.getProperty("ftp.enabled");
if (StringUtils.hasLength(ftpEnabled) && "true".equals(ftpEnabled)) {
log.info("ftpEnabled: {} StorageUtils -> FtpStorageUtils", ftpEnabled);
return new FtpStorageUtils(environment, messageUtil);
}
log.info("ftpEnabled: {} StorageUtils -> FileStorageUtils", ftpEnabled);
return new FileStorageUtils(environment, messageUtil);
}
}

View File

@@ -0,0 +1,129 @@
package org.egovframe.cloud.portalservice.domain.attachment;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
/**
* org.egovframe.cloud.portalservice.domain.attachment.Attachment
* <p>
* 첨부파일 엔티티 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
/**
* @TODO
* 관련 엔티티를 어떻게 처리하는지 에 따라
* 컬럼명이 변경되거나 삭제될 수 있음.
* 아직 용어사전에 넣지 않았으므로 기능 완료되면 용어사전에도 fix된 컬럼명을 넣어야 함.
* 2021/07/26 shinmj!!
*/
@Getter
@NoArgsConstructor
@ToString
@Entity
public class Attachment extends BaseEntity {
@EmbeddedId
private AttachmentId attachmentId;
/**
* 복합키를 HTTP URI에 표현하기 힘드므로 대체키를 추가한다.
*/
@Column(name = "attachment_id", length = 50, nullable = false, unique = true)
private String uniqueId;
@Column(nullable = false, length = 200)
private String physicalFileName;
@Column(nullable = false, length = 200)
private String originalFileName;
@Column(name = "attachment_size", length = 20)
private Long size;
@Column(name = "file_type_value", length = 100)
private String fileType;
@Column(name = "download_count", length = 15)
private Long downloadCnt;
@Column(name = "delete_at", columnDefinition = "boolean default false")
private Boolean isDelete;
@Column(length = 200)
private String entityName;
@Column(length = 50)
private String entityId;
@Builder
public Attachment(AttachmentId attachmentId, String uniqueId,
String physicalFileName, String originalFileName,
Long size, String fileType,
String entityName, String entityId) {
this.attachmentId = attachmentId;
this.uniqueId = uniqueId;
this.physicalFileName = physicalFileName;
this.originalFileName = originalFileName;
this.size = size;
this.fileType = fileType;
this.entityName = entityName;
this.entityId = entityId;
this.isDelete = false;
this.downloadCnt = 0L;
}
/**
* 삭제 여부 토글
*
* @param isDelete
* @return
*/
public Attachment updateIsDelete(Boolean isDelete) {
this.isDelete = isDelete;
return this;
}
/**
* 첨부파일 다운로드 할 때 마다 Download 횟수 + 1
*
* @return
*/
public Attachment updateDownloadCnt() {
this.downloadCnt = getDownloadCnt() == null ? 1 : getDownloadCnt() + 1;
return this;
}
/**
* entity 정보 update
*
* @param entityName
* @param entityId
* @return
*/
public Attachment updateEntity(String entityName, String entityId) {
this.entityName = entityName;
this.entityId = entityId;
return this;
}
}

View File

@@ -0,0 +1,48 @@
package org.egovframe.cloud.portalservice.domain.attachment;
import lombok.Builder;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.UUID;
/**
* org.egovframe.cloud.portalservice.domain.attachment.AttachmentId
* <p>
* 첨부파일 엔티티 복합키 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Data
@Embeddable
public class AttachmentId implements Serializable {
@Column(name = "attachment_code", length = 20)
private String code;
@Column(name = "attachment_seq", length = 15)
private Long seq;
@Builder
public AttachmentId (String code, Long seq) {
this.code = code;
this.seq = seq;
}
public AttachmentId () {
this.code = UUID.randomUUID().toString();
this.seq = 1L;
}
}

View File

@@ -0,0 +1,27 @@
package org.egovframe.cloud.portalservice.domain.attachment;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
/**
* org.egovframe.cloud.portalservice.domain.attachment.AttachmentRepository
* <p>
* 첨부파일 repository interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
public interface AttachmentRepository extends JpaRepository<Attachment, AttachmentId>, AttachmentRepositoryCustom {
Optional<Attachment> findAllByUniqueId(String uniqueId);
}

View File

@@ -0,0 +1,31 @@
package org.egovframe.cloud.portalservice.domain.attachment;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentResponseDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.attachment.AttachmentRepositoryCustom
* <p>
* 첨부파일 querydsl interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
public interface AttachmentRepositoryCustom {
List<Attachment> findByCode(String attachmentCode);
AttachmentId getId(String attachmentCode);
Page<AttachmentResponseDto> search(RequestDto searchRequestDto, Pageable pageable);
}

View File

@@ -0,0 +1,130 @@
package org.egovframe.cloud.portalservice.domain.attachment;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.attachment.dto.AttachmentResponseDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import java.util.List;
import static com.querydsl.core.types.Projections.constructor;
import static org.egovframe.cloud.portalservice.domain.attachment.QAttachment.attachment;
import static org.springframework.util.StringUtils.hasLength;
/**
* org.egovframe.cloud.portalservice.domain.attachment.AttachmentRepositoryImpl
* <p>
* 첨부파일 querydsl 구현 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/14
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/14 shinmj 최초 생성
* </pre>
*/
@Slf4j
@RequiredArgsConstructor
public class AttachmentRepositoryImpl implements AttachmentRepositoryCustom{
/**
* DML 생성을위한 Querydsl 팩토리 클래스
*/
private final JPAQueryFactory queryFactory;
/**
* code로 첨부파일 검색
*
* @param attachmentCode
* @return
*/
@Override
public List<Attachment> findByCode(String attachmentCode) {
return queryFactory.selectFrom(attachment)
.where(attachment.attachmentId.code.eq(attachmentCode), attachment.isDelete.eq(false))
.orderBy(attachment.attachmentId.seq.asc())
.fetch();
}
/**
* 첨부파일 복합키 seq 조회하여 생성
*
* @param attachmentCode
* @return
*/
@Override
public AttachmentId getId(String attachmentCode) {
Long seq = queryFactory.select(
attachment.attachmentId.seq.max()
)
.from(attachment)
.where(attachment.attachmentId.code.eq(attachmentCode))
.fetchOne();
return AttachmentId.builder()
.code(attachmentCode)
.seq(seq+1L)
.build();
}
/**
* 관리자 - 첨부파일 목록 조회
*
* @param searchRequestDto
* @param pageable
* @return
*/
@Override
public Page<AttachmentResponseDto> search(RequestDto searchRequestDto, Pageable pageable) {
QueryResults<AttachmentResponseDto> results =
queryFactory.select(constructor(AttachmentResponseDto.class, attachment))
.from(attachment)
.where(
searchTextLike(searchRequestDto)
)
.orderBy(
attachment.createdDate.desc(),
attachment.attachmentId.code.asc(),
attachment.attachmentId.seq.asc()
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetchResults();
return new PageImpl<>(results.getResults(), pageable, results.getTotal());
}
/**
* dynamic query binding
*
* @param requestDto
* @return
*/
private BooleanExpression searchTextLike(RequestDto requestDto) {
final String type = requestDto.getKeywordType();
final String value = requestDto.getKeyword();
if (!hasLength(type) || !hasLength(value)) {
return null;
}
if ("id".equals(type)) {
return attachment.attachmentId.code.containsIgnoreCase(value);
} else if ("name".equals(type)) {
return attachment.originalFileName.containsIgnoreCase(value);
}
return null;
}
}

View File

@@ -0,0 +1,164 @@
package org.egovframe.cloud.portalservice.domain.banner;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.portalservice.domain.menu.Site;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
/**
* org.egovframe.cloud.portalservice.domain.banner.Banner
* <p>
* 배너 엔티티 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Entity
public class Banner extends BaseEntity {
/**
* 배너 번호
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer bannerNo;
/**
* 배너 구분 코드
*/
@Column(nullable = false, length = 20)
private String bannerTypeCode;
/**
* 배너 제목
*/
@Column(nullable = false, length = 100)
private String bannerTitle;
/**
* 첨부파일 코드
*/
@Column(nullable = false, length = 255)
private String attachmentCode;
/**
* url 주소
*/
@Column(length = 500)
private String urlAddr;
/**
* 새 창 여부
*/
@Column(nullable = false, columnDefinition = "tinyint(1) default '0'")
private Boolean newWindowAt;
/**
* 배너 내용
*/
@Column(length = 2000)
private String bannerContent;
/**
* 정렬 순서
*/
@Column(nullable = false, columnDefinition = "mediumint(5) default '99999'")
private Integer sortSeq;
/**
* 사용 여부
*/
@Column(nullable = false, columnDefinition = "tinyint(1) default '1'")
private Boolean useAt;
/**
* 사이트 정보
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "site_id")
private Site site;
/**
* 빌더 패턴 클래스 생성자
*
* @param bannerNo 배너 번호
* @param bannerTypeCode 배너 구분 코드
* @param bannerTitle 배너 제목
* @param attachmentCode 첨부파일 코드
* @param urlAddr url 주소
* @param newWindowAt 새 창 여부
* @param bannerContent 배너 내용
* @param sortSeq 정렬 순서
* @param useAt 사용 여부
*/
@Builder
public Banner(Integer bannerNo, String bannerTypeCode, String bannerTitle, String attachmentCode,
String urlAddr, Boolean newWindowAt, String bannerContent, Integer sortSeq, Boolean useAt, Site site) {
this.bannerNo = bannerNo;
this.bannerTypeCode = bannerTypeCode;
this.bannerTitle = bannerTitle;
this.attachmentCode = attachmentCode;
this.urlAddr = urlAddr;
this.newWindowAt = newWindowAt;
this.bannerContent = bannerContent;
this.sortSeq = sortSeq;
this.useAt = useAt;
this.site = site;
}
/**
* 배너 속성 값 수정
*
* @param bannerTypeCode 배너 구분 코드
* @param bannerTitle 배너 제목
* @param attachmentCode 첨부파일 코드
* @param urlAddr url 주소
* @param bannerContent 배너 내용
* @return Banner 배너 엔티티
*/
public Banner update(String bannerTypeCode, String bannerTitle, String attachmentCode,
String urlAddr, Boolean newWindowAt, String bannerContent, Integer sortSeq, Site site) {
this.bannerTypeCode = bannerTypeCode;
this.bannerTitle = bannerTitle;
this.attachmentCode = attachmentCode;
this.urlAddr = urlAddr;
this.newWindowAt = newWindowAt;
this.bannerContent = bannerContent;
this.sortSeq = sortSeq;
this.site = site;
return this;
}
/**
* 배너 사용 여부 수정
*
* @param useAt 사용 여부
* @return Banner 배너 엔티티
*/
public Banner updateUseAt(Boolean useAt) {
this.useAt = useAt;
return this;
}
}

View File

@@ -0,0 +1,24 @@
package org.egovframe.cloud.portalservice.domain.banner;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* org.egovframe.cloud.portalservice.domain.banner.BannerRepository
* <p>
* 배너 레파지토리 인터페이스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
public interface BannerRepository extends JpaRepository<Banner, Integer>, BannerRepositoryCustom {
}

View File

@@ -0,0 +1,75 @@
package org.egovframe.cloud.portalservice.domain.banner;
import java.util.List;
import java.util.Optional;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerImageResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerListResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerRequestDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
/**
* org.egovframe.cloud.portalservice.domain.banner.BannerRepositoryCustom
* <p>
* 배너 Querydsl 인터페이스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
public interface BannerRepositoryCustom {
/**
* 배너 페이지 목록 조회
*
* @param requestDto 배너 목록 요청 DTO
* @param pageable 페이지 정보
* @return Page<BannerListResponseDto> 페이지 배너 목록 응답 DTO
*/
Page<BannerListResponseDto> findPage(BannerRequestDto requestDto, Pageable pageable);
/**
* 배너 목록 조회
*
* @param bannerTypeCode 배너 유형 코드
* @param bannerCount 배너 수
* @param useAt 사용 여부
* @return List<BannerImageResponseDto> 배너 이미지 응답 DTO List
*/
List<BannerImageResponseDto> findList(String bannerTypeCode, Integer bannerCount, Boolean useAt, Long siteId);
/**
* 배너 다음 정렬 순서 조회
*
* @return Integer 다음 정렬 순서
*/
Integer findNextSortSeq(Long siteId);
/**
* 배너 정렬 순서 수정
*
* @param startSortSeq 시작 정렬 순서
* @param endSortSeq 종료 정렬 순서
* @param increaseSortSeq 증가 정렬 순서
* @return Long 처리 건수
*/
Long updateSortSeq(Integer startSortSeq, Integer endSortSeq, int increaseSortSeq, Long siteId);
/**
* 정렬 순서로 배너 단건 조회
*
* @param sortSeq 정렬 순서
* @return Banner 배너 엔티티
*/
Optional<Banner> findBySortSeqAndSiteId(Integer sortSeq, Long siteId);
}

View File

@@ -0,0 +1,221 @@
package org.egovframe.cloud.portalservice.domain.banner;
import static com.querydsl.core.types.Projections.*;
import java.util.List;
import java.util.Optional;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerImageResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerListResponseDto;
import org.egovframe.cloud.portalservice.api.banner.dto.BannerRequestDto;
import org.egovframe.cloud.portalservice.domain.attachment.QAttachment;
import org.egovframe.cloud.portalservice.domain.code.QCode;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
/**
* org.egovframe.cloud.portalservice.domain.banner.BannerRepositoryImpl
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/08/18
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/18 jooho 최초 생성
* </pre>
*/
@RequiredArgsConstructor
public class BannerRepositoryImpl implements BannerRepositoryCustom {
/**
* DML 생성을위한 Querydsl 팩토리 클래스
*/
private final JPAQueryFactory jpaQueryFactory;
/**
* 배너 페이지 목록 조회
* 가급적 Entity 보다는 Dto를 리턴 - Entity 조회시 hibernate 캐시, 불필요 컬럼 조회, oneToOne N+1 문제 발생
*
* @param requestDto 요청 DTO
* @param pageable 페이지 정보
* @return Page<BannerListResponseDto> 페이지 배너 목록 응답 DTO
*/
public Page<BannerListResponseDto> findPage(BannerRequestDto requestDto, Pageable pageable) {
QueryResults<BannerListResponseDto> result = jpaQueryFactory
.select(fields(BannerListResponseDto.class,
QBanner.banner.bannerNo,
QBanner.banner.bannerTypeCode,
Expressions.as(QCode.code.codeName, "bannerTypeCodeName"),
QBanner.banner.bannerTitle,
QBanner.banner.useAt,
QBanner.banner.createdDate,
QBanner.banner.site.name.as("siteName")
))
.from(QBanner.banner)
.leftJoin(QCode.code).on(QBanner.banner.bannerTypeCode.eq(QCode.code.codeId).and(QCode.code.parentCodeId.eq("banner_type_code")))
.fetchJoin()
.where(getBooleanExpressionKeyword(requestDto), getEqualsBooleanExpression("siteId", requestDto.getSiteId()))
.orderBy(QBanner.banner.site.sortSeq.asc(), QBanner.banner.sortSeq.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize()) //페이징
.fetchResults();
return new PageImpl<>(result.getResults(), pageable, result.getTotal());
}
/**
* 배너 목록 조회
*
* @param bannerTypeCode 배너 유형 코드
* @param bannerCount 배너 수
* @param useAt 사용 여부
* @return List<BannerImageResponseDto> 배너 이미지 응답 DTO List
*/
public List<BannerImageResponseDto> findList(String bannerTypeCode, Integer bannerCount, Boolean useAt, Long siteId) {
JPQLQuery<BannerImageResponseDto> query = jpaQueryFactory
.select(constructor(BannerImageResponseDto.class,
QBanner.banner.bannerNo,
QBanner.banner.bannerTypeCode,
QBanner.banner.bannerTitle,
QBanner.banner.attachmentCode,
JPAExpressions.select(QAttachment.attachment.uniqueId)
.from(QAttachment.attachment)
.where(QAttachment.attachment.attachmentId.code.eq(QBanner.banner.attachmentCode)
.and(QAttachment.attachment.isDelete.eq(Boolean.FALSE))
.and(QAttachment.attachment.attachmentId.seq.eq(
JPAExpressions.select(QAttachment.attachment.attachmentId.seq.max())
.from(QAttachment.attachment)
.where(QAttachment.attachment.attachmentId.code.eq(QBanner.banner.attachmentCode)
.and(QAttachment.attachment.isDelete.eq(Boolean.FALSE)))))),
QBanner.banner.urlAddr,
QBanner.banner.newWindowAt,
QBanner.banner.bannerContent
))
.from(QBanner.banner)
.where(QBanner.banner.site.id.eq(siteId),
getEqualsBooleanExpression("bannerTypeCode", bannerTypeCode),
getEqualsBooleanExpression("useAt", useAt))
.orderBy(QBanner.banner.sortSeq.asc());
if (bannerCount != null && bannerCount > 0) {
query.limit(bannerCount);
}
return query.fetch();
}
/**
* 배너 다음 정렬 순서 조회
*
* @param siteId siteId
* @return Integer 다음 정렬 순서
*/
public Integer findNextSortSeq(Long siteId) {
return jpaQueryFactory
.select(QBanner.banner.sortSeq.max().add(1).coalesce(1))
.from(QBanner.banner)
.where(QBanner.banner.site.id.eq(siteId))
.fetchOne();
}
/**
* 배너 정렬 순서 수정
*
* @param startSortSeq 시작 정렬 순서
* @param endSortSeq 종료 정렬 순서
* @param increaseSortSeq 증가 정렬 순서
* @param siteId siteId
* @return Long 수정 건수
*/
public Long updateSortSeq(Integer startSortSeq, Integer endSortSeq, int increaseSortSeq, Long siteId) {
return jpaQueryFactory.update(QBanner.banner)
.set(QBanner.banner.sortSeq, QBanner.banner.sortSeq.add(increaseSortSeq))
.where(QBanner.banner.site.id.eq(siteId),
isGoeSortSeq(startSortSeq),
isLoeSortSeq(endSortSeq))
.execute();
}
@Override
public Optional<Banner> findBySortSeqAndSiteId(Integer sortSeq, Long siteId) {
return Optional.ofNullable(jpaQueryFactory.selectFrom(QBanner.banner)
.where(QBanner.banner.site.id.eq(siteId), QBanner.banner.sortSeq.eq(sortSeq)).fetchOne());
}
/**
* 엔티티 속성별 동적 검색 표현식 리턴
*
* @param attributeName 속성 명
* @param attributeValue 속성 값
* @return BooleanExpression 검색 표현식
*/
private BooleanExpression getEqualsBooleanExpression(String attributeName, Object attributeValue) {
if (attributeValue == null || "".equals(attributeValue.toString())) return null;
switch (attributeName) {
case "bannerTypeCode": // 배너 유형 코드
return QBanner.banner.bannerTypeCode.eq((String) attributeValue);
case "useAt": // 사용 여부
return QBanner.banner.useAt.eq((Boolean) attributeValue);
case "siteId":
return QBanner.banner.site.id.eq((Long) attributeValue);
default:
return null;
}
}
/**
* 요청 DTO로 동적 검색 표현식 리턴
*
* @param requestDto 요청 DTO
* @return BooleanExpression 검색 표현식
*/
private BooleanExpression getBooleanExpressionKeyword(BannerRequestDto requestDto) {
if (requestDto.getKeyword() == null || "".equals(requestDto.getKeyword())) return null;
switch (requestDto.getKeywordType()) {
case "bannerTitle": // 배너 제목
return QBanner.banner.bannerTitle.containsIgnoreCase(requestDto.getKeyword());
case "bannerContent": // 배너 내용
return QBanner.banner.bannerContent.containsIgnoreCase(requestDto.getKeyword());
default:
return null;
}
}
/**
* 정렬 순서 이하 검색 표현식
*
* @param sortSeq 정렬 순서
* @return BooleanExpression 검색 표현식
*/
private BooleanExpression isLoeSortSeq(Integer sortSeq) {
return sortSeq == null ? null : QBanner.banner.sortSeq.loe(sortSeq);
}
/**
* 정렬 순서 이상 검색 표현식
*
* @param sortSeq 정렬 순서
* @return BooleanExpression 검색 표현식
*/
private BooleanExpression isGoeSortSeq(Integer sortSeq) {
return sortSeq == null ? null : QBanner.banner.sortSeq.goe(sortSeq);
}
}

View File

@@ -0,0 +1,51 @@
package org.egovframe.cloud.portalservice.domain.board;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.*;
/**
* org.egovframe.cloud.boardservice.domain.board.Board
* <p>
* 게시판 엔티티 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/26
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/26 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@Entity
public class Board extends BaseEntity {
/**
* 게시판 번호
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer boardNo;
/**
* 게시판 제목
*/
@Column(nullable = false, length = 100)
private String boardName;
/**
* 스킨 유형 코드
*/
@Column(nullable = false, length = 20)
private String skinTypeCode;
}

View File

@@ -0,0 +1,115 @@
package org.egovframe.cloud.portalservice.domain.code;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* org.egovframe.cloud.portalservice.domain.code.Code
* <p>
* 공통코드 엔티티
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@Entity
public class Code extends BaseEntity {
@Id
@Column(length = 20)
private String codeId; // 코드ID
@Column(length = 20)
private String parentCodeId; // 상위 코드ID
@Column(nullable = false, length = 500)
private String codeName; // 코드 명
@Column(length = 500)
private String codeDescription; // 코드 설명
@Column(columnDefinition = "SMALLINT(3)")
private Integer sortSeq; // 정렬 순서
@Column(nullable = false)
private Boolean useAt; // 사용 여부
@Column(nullable = false, name = "readonly_at")
private Boolean readonly; // 수정하면 안되는 읽기전용 공통코드
@Builder
public Code(String codeId, String parentCodeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt, Boolean readonly) {
this.codeId = codeId;
this.parentCodeId = parentCodeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
this.readonly = readonly;
}
/**
* 공통코드 정보를 수정한다.
*
* @param codeName
* @param codeDescription
* @param sortSeq
* @param useAt
* @return
*/
public Code update(String codeName, String codeDescription, Integer sortSeq, Boolean useAt) {
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
return this;
}
/**
* 상세공통코드 정보를 수정한다.
*
* @param codeName
* @param codeDescription
* @param sortSeq
* @param useAt
* @return
*/
public Code updateDetail(String parentCodeId, String codeName, String codeDescription, Integer sortSeq, Boolean useAt) {
this.parentCodeId = parentCodeId;
this.codeName = codeName;
this.codeDescription = codeDescription;
this.sortSeq = sortSeq;
this.useAt = useAt;
return this;
}
/**
* 공통코드 사용여부를 수정한다.
*
* @param useAt
* @return
*/
public Code updateUseAt(boolean useAt) {
this.useAt = useAt;
return this;
}
}

View File

@@ -0,0 +1,27 @@
package org.egovframe.cloud.portalservice.domain.code;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
/**
* org.egovframe.cloud.portalservice.domain.code.CodeRepository
* <p>
* 공통코드 엔티티를 위한 Repository
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
public interface CodeRepository extends JpaRepository<Code, String>, CodeRepositoryCustom {
Optional<Code> findByCodeId(String codeId);
}

View File

@@ -0,0 +1,86 @@
package org.egovframe.cloud.portalservice.domain.code;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.code.dto.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.code.CodeRepositoryCustom
* <p>
* 공통코드 Querydsl interface
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
public interface CodeRepositoryCustom {
/**
* 공통코드 목록
*
* @param requestDto
* @param pageable
* @return
*/
Page<CodeListResponseDto> findAllByKeyword(RequestDto requestDto, Pageable pageable);
/**
* 공통코드 상세 목록
*
* @param requestDto
* @param pageable
* @return
*/
Page<CodeDetailListResponseDto> findAllDetailByKeyword(CodeDetailRequestDto requestDto, Pageable pageable);
/**
* 공통코드 목록 - parentCodeId 가 없는 상위공통코드
*
* @return
*/
List<CodeResponseDto> findAllParent();
/**
* 공통코드 상세 목록 - parentCodeId 에 해당하는 사용중인 공통코드 목록
*
* @param parentCodeId
* @return
*/
List<CodeDetailResponseDto> findDetailsByParentCodeIdUseAt(String parentCodeId);
/**
* 공통코드 상세 목록 - parentCodeId 에 해당하는 사용중인 공통코드 목록
* 사용여부가 false 로 변경된 경우에도 인자로 받은 공통코드를 목록에 포함되도록 한다
*
* @param parentCodeId
* @param codeId
* @return
*/
List<CodeDetailResponseDto> findDetailsUnionCodeIdByParentCodeId(String parentCodeId, String codeId);
/**
* 부모 공통 코드 단건 조회
*
* @param codeId
* @return
*/
CodeResponseDto findParentByCodeId(String codeId);
/**
* 공통코드 parentCodeId 에 해당코드가 존재하는지 여부를 알기 위해 건수를 카운트한다
* @param codeId
* @return
*/
long countByParentCodeId(String codeId);
}

View File

@@ -0,0 +1,274 @@
package org.egovframe.cloud.portalservice.domain.code;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.code.dto.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.support.PageableExecutionUtils;
import javax.persistence.EntityManager;
import java.util.List;
import static com.querydsl.core.types.Projections.fields;
import static org.egovframe.cloud.portalservice.domain.code.QCode.code;
import static org.springframework.util.StringUtils.hasLength;
/**
* org.egovframe.cloud.portalservice.domain.code.CodeRepositoryImpl
* <p>
* 공통코드 Querydsl 구현 클래스
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/12 jaeyeolkim 최초 생성
* </pre>
*/
@RequiredArgsConstructor
public class CodeRepositoryImpl implements CodeRepositoryCustom {
private final JPAQueryFactory queryFactory;
/**
* 공통코드 목록 조회
*
* @param requestDto
* @param pageable
* @return
*/
@Override
public Page<CodeListResponseDto> findAllByKeyword(RequestDto requestDto, Pageable pageable) {
QCode childCode = new QCode("childCode");
List<CodeListResponseDto> content =
queryFactory
.select(fields(CodeListResponseDto.class,
code.codeId,
code.codeName,
code.codeDescription,
code.useAt,
code.readonly,
childCode.codeId.count().as("codeDetailCount")
))
.from(code)
.leftJoin(childCode).on(code.parentCodeId.eq(childCode.codeId))
.where(
code.parentCodeId.isNull(),
keyword(requestDto.getKeywordType(), requestDto.getKeyword())
)
.groupBy(code.codeId,
code.codeName,
code.codeDescription,
code.useAt,
code.readonly)
.orderBy(code.sortSeq.asc(), code.createdDate.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
JPAQuery<Code> query = queryFactory
.selectFrom(code)
.where(
code.parentCodeId.isNull(),
keyword(requestDto.getKeywordType(), requestDto.getKeyword())
);
return PageableExecutionUtils.getPage(content, pageable, query::fetchCount);
}
/**
* 공통코드 상세 목록 조회
*
* @param requestDto
* @param pageable
* @return
*/
@Override
public Page<CodeDetailListResponseDto> findAllDetailByKeyword(CodeDetailRequestDto requestDto, Pageable pageable) {
List<CodeDetailListResponseDto> content =
queryFactory
.select(fields(CodeDetailListResponseDto.class,
code.parentCodeId,
code.codeId,
code.codeName,
code.sortSeq,
code.useAt,
code.readonly
))
.from(code)
.where(
code.parentCodeId.isNotNull(),
parentCodeIdEq(requestDto.getParentCodeId()),
keyword(requestDto.getKeywordType(), requestDto.getKeyword())
)
.groupBy(code.codeId,
code.codeName,
code.sortSeq,
code.useAt,
code.readonly)
.orderBy(code.parentCodeId.asc(), code.sortSeq.asc(), code.createdDate.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
JPAQuery<Code> query = queryFactory
.selectFrom(code)
.where(
code.parentCodeId.isNotNull(),
parentCodeIdEq(requestDto.getParentCodeId()),
keyword(requestDto.getKeywordType(), requestDto.getKeyword())
);
return PageableExecutionUtils.getPage(content, pageable, query::fetchCount);
}
/**
* 공통코드 상세 목록 - parentCodeId 에 해당하는 사용중인 공통코드 목록
*
* @param parentCodeId
* @return
*/
@Override
public List<CodeDetailResponseDto> findDetailsByParentCodeIdUseAt(String parentCodeId) {
return queryFactory
.select(fields(CodeDetailResponseDto.class,
code.parentCodeId,
code.codeId,
code.codeName,
code.sortSeq,
code.useAt,
code.readonly
))
.from(code)
.where(
code.parentCodeId.eq(parentCodeId)
.and(code.useAt.eq(true))
)
.orderBy(code.sortSeq.asc())
.fetch();
}
/**
* 공통코드 상세 목록 - parentCodeId 에 해당하는 사용중인 공통코드 목록
* 사용여부가 false 로 변경된 경우에도 인자로 받은 공통코드를 목록에 포함되도록 한다
*
* @param parentCodeId
* @param codeId
* @return
*/
@Override
public List<CodeDetailResponseDto> findDetailsUnionCodeIdByParentCodeId(String parentCodeId, String codeId) {
return queryFactory
.select(fields(CodeDetailResponseDto.class,
code.parentCodeId,
code.codeId,
code.codeName,
code.sortSeq,
code.useAt,
code.readonly
))
.from(code)
.where(
code.parentCodeId.eq(parentCodeId)
.and(code.useAt.eq(true).or(code.codeId.eq(codeId)))
)
.orderBy(code.sortSeq.asc())
.fetch();
}
/**
* 공통코드 목록 - parentCodeId 가 없는 상위공통코드
*
* @return
*/
@Override
public List<CodeResponseDto> findAllParent() {
return queryFactory
.select(fields(CodeResponseDto.class,
code.codeId,
code.codeName,
code.sortSeq,
code.useAt
))
.from(code)
.where(code.parentCodeId.isNull())
.orderBy(code.sortSeq.asc())
.fetch();
}
/**
* 부모 공통코드 단건 조회
*
* @param codeId
* @return
*/
@Override
public CodeResponseDto findParentByCodeId(String codeId) {
QCode parent = new QCode("parent");
return queryFactory
.select(fields(CodeResponseDto.class,
parent.codeId,
parent.codeName,
parent.useAt
))
.from(code)
.join(parent)
.on(code.parentCodeId.eq(parent.codeId))
.where(code.codeId.eq(codeId))
.fetchOne();
}
/**
* 공통코드 parentCodeId 에 해당코드가 존재하는지 여부를 알기 위해 건수를 카운트한다
*
* @param codeId
* @return
*/
@Override
public long countByParentCodeId(String codeId) {
return queryFactory
.selectFrom(code)
.where(code.parentCodeId.eq(codeId))
.fetchCount();
}
/**
* 공통코드 조회조건
*
* @param keywordType
* @param keyword
* @return
*/
private BooleanExpression keyword(String keywordType, String keyword) {
if (!hasLength(keywordType) || !hasLength(keyword)) {
return null;
}
if ("codeId".equals(keywordType)) {
return code.codeId.containsIgnoreCase(keyword);
} else if ("codeName".equals(keywordType)) {
return code.codeName.containsIgnoreCase(keyword);
}
return null;
}
/**
* 공통코드 상세 목록 추가 조회조건 - 상위코드
*
* @param parentCodeId
* @return
*/
private BooleanExpression parentCodeIdEq(String parentCodeId) {
return hasLength(parentCodeId) ? code.parentCodeId.eq(parentCodeId) : null;
}
}

View File

@@ -0,0 +1,93 @@
package org.egovframe.cloud.portalservice.domain.content;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
/**
* org.egovframe.cloud.portalservice.domain.content.Content
* <p>
* 컨텐츠 엔티티 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@Entity
@DynamicInsert
@DynamicUpdate
public class Content extends BaseEntity {
/**
* 컨텐츠 번호
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer contentNo;
/**
* 컨텐츠 명
*/
@Column(nullable = false, length = 100)
private String contentName;
/**
* 컨텐츠 비고
*/
@Column(length = 200)
private String contentRemark;
/**
* 컨텐츠 값
*/
@Column(nullable = false, columnDefinition = "longtext")
private String contentValue;
/**
* 빌더 패턴 클래스 생성자
*
* @param contentNo 컨텐츠 번호
* @param contentName 컨텐츠 명
* @param contentRemark 컨텐츠 비고
* @param contentValue 컨텐츠 값
*/
@Builder
public Content(Integer contentNo, String contentName, String contentRemark, String contentValue) {
this.contentNo = contentNo;
this.contentName = contentName;
this.contentRemark = contentRemark;
this.contentValue = contentValue;
}
/**
* 컨텐츠 속성 값 수정
*
* @param contentName 컨텐츠 명
* @param contentRemark 컨텐츠 비고
* @param contentValue 컨텐츠 값
* @return Content 컨텐츠 엔티티
*/
public Content update(String contentName, String contentRemark, String contentValue) {
this.contentName = contentName;
this.contentRemark = contentRemark;
this.contentValue = contentValue;
return this;
}
}

View File

@@ -0,0 +1,24 @@
package org.egovframe.cloud.portalservice.domain.content;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* org.egovframe.cloud.portalservice.domain.content.ContentRepository
* <p>
* 컨텐츠 레파지토리 인터페이스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
public interface ContentRepository extends JpaRepository<Content, Integer>, ContentRepositoryCustom {
}

View File

@@ -0,0 +1,36 @@
package org.egovframe.cloud.portalservice.domain.content;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentListResponseDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
/**
* org.egovframe.cloud.portalservice.domain.content.ContentRepositoryCustom
* <p>
* 컨텐츠 Querydsl 인터페이스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/23
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/23 jooho 최초 생성
* </pre>
*/
public interface ContentRepositoryCustom {
/**
* 컨텐츠 페이지 목록 조회
*
* @param requestDto 컨텐츠 목록 요청 DTO
* @param pageable 페이지 정보
* @return Page<ContentListResponseDto> 페이지 컨텐츠 목록 응답 DTO
*/
Page<ContentListResponseDto> findPage(RequestDto requestDto, Pageable pageable);
}

View File

@@ -0,0 +1,110 @@
package org.egovframe.cloud.portalservice.domain.content;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.portalservice.api.content.dto.ContentListResponseDto;
import org.egovframe.cloud.portalservice.api.content.dto.QContentListResponseDto;
import org.egovframe.cloud.portalservice.domain.user.QUser;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import com.google.common.base.CaseFormat;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
/**
* org.egovframe.cloud.portalservice.domain.content.ContentRepositoryImpl
* <p>
* 컨텐츠 Querydsl 구현 클래스
*
* @author 표준프레임워크센터 jooho
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jooho 최초 생성
* </pre>
*/
@RequiredArgsConstructor
public class ContentRepositoryImpl implements ContentRepositoryCustom {
/**
* DML 생성을위한 Querydsl 팩토리 클래스
*/
private final JPAQueryFactory jpaQueryFactory;
/**
* 컨텐츠 페이지 목록 조회
* 가급적 Entity 보다는 Dto를 리턴 - Entity 조회시 hibernate 캐시, 불필요 컬럼 조회, oneToOne N+1 문제 발생
*
* @param requestDto 요청 DTO
* @param pageable 페이지 정보
* @return Page<ContentListResponseDto> 페이지 컨텐츠 목록 응답 DTO
*/
@Override
public Page<ContentListResponseDto> findPage(RequestDto requestDto, Pageable pageable) {
JPQLQuery<ContentListResponseDto> query = jpaQueryFactory
.select(new QContentListResponseDto(
QContent.content.contentNo,
QContent.content.contentName,
Expressions.as(QUser.user.userName, "lastModifiedBy"),
QContent.content.modifiedDate
))
.from(QContent.content)
.leftJoin(QUser.user).on(QContent.content.lastModifiedBy.eq(QUser.user.userId))
.fetchJoin()
.where(getBooleanExpressionKeyword(requestDto));
//정렬
pageable.getSort().stream().forEach(sort -> {
Order order = sort.isAscending() ? Order.ASC : Order.DESC;
String property = sort.getProperty();
Path<Object> target = Expressions.path(Object.class, QContent.content, CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, property));
@SuppressWarnings({ "rawtypes", "unchecked" })
OrderSpecifier<?> orderSpecifier = new OrderSpecifier(order, target);
query.orderBy(orderSpecifier);
});
QueryResults<ContentListResponseDto> result = query
.offset(pageable.getOffset())
.limit(pageable.getPageSize()) //페이징
.fetchResults();
return new PageImpl<>(result.getResults(), pageable, result.getTotal());
}
/**
* 요청 DTO로 동적 검색 표현식 리턴
*
* @param requestDto 요청 DTO
* @return BooleanExpression 검색 표현식
*/
private BooleanExpression getBooleanExpressionKeyword(RequestDto requestDto) {
if (requestDto.getKeyword() == null || "".equals(requestDto.getKeyword())) return null;
switch (requestDto.getKeywordType()) {
case "contentName": // 컨텐츠 명
return QContent.content.contentName.containsIgnoreCase(requestDto.getKeyword());
case "contentRemark": // 컨텐츠 비고
return QContent.content.contentRemark.containsIgnoreCase(requestDto.getKeyword());
case "contentValue": // 컨텐츠 값
return QContent.content.contentValue.containsIgnoreCase(requestDto.getKeyword());
default:
return null;
}
}
}

View File

@@ -0,0 +1,203 @@
package org.egovframe.cloud.portalservice.domain.menu;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuUpdateRequestDto;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.menu.Menu
* <p>
* 메뉴관리 > Menu 도메인 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@Entity
@ToString
public class Menu extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menu_id")
private Long id; // id
@Column( length = 100)
private String menuKorName; // 메뉴명 kor
@Column( length = 100)
private String menuEngName; // 메뉴명 eng
@Column(name = "type_id", length = 20)
private String menuType; // 메뉴 유형 공통 코드 id
@Column
private Integer connectId; // 연결된 컨텐츠 or 게시판 id
@Column(length = 200)
private String urlPath; // 링크 url
@Column(name = "use_at", columnDefinition = "boolean default true")
private Boolean isUse; // 사용 여부
@Column(name = "show_at", columnDefinition = "boolean default true")
private Boolean isShow; // 출력 여부
@Column(name = "blank_at", columnDefinition = "boolean default false")
private Boolean isBlank; // 연결 형태 (새창/현재창)
@Column(name = "sub_name", length = 200)
private String subName; // 메뉴 서브명
@Column(name = "menu_description", length = 500)
private String description; // 메뉴 설명
@Column(columnDefinition = "SMALLINT(3)")
private Integer sortSeq; // 정렬 순서
@Column(name = "icon_name", length = 100)
private String icon; // 아이콘 class
@Column(name = "level_no", length = 15)
private Integer level;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_menu_id")
private Menu parent;
@ToString.Exclude
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Menu> children = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "site_id")
private Site site;
@ToString.Exclude
@OneToMany(fetch = FetchType.LAZY, mappedBy = "menu", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<MenuRole> menuRoles = new ArrayList<>();
@Builder
public Menu(String menuKorName, Menu parent, Integer sortSeq, Site site, Integer level, Boolean isUse, Boolean isShow) {
this.menuKorName = menuKorName;
this.parent = parent;
this.sortSeq = sortSeq;
this.site = site;
this.level = level;
this.isShow = isShow;
this.isUse = isUse;
}
/**
* 메뉴명 변경
*
* @param menuKorName
* @return
*/
public Menu updateName(String menuKorName) {
this.menuKorName = menuKorName;
return this;
}
/**
* 드래그앤드랍으로 변경 시 상위메뉴, 정렬순서 수정
*
* @param parent
* @param sortSeq
* @return
*/
public Menu updateDnD(Menu parent, Integer sortSeq, Integer level) {
this.sortSeq = sortSeq;
this.level = level;
if (parent == null) {
Menu oldParent = this.getParent();
if (oldParent == null) {
return this;
}
Menu old = oldParent.getChildren().stream().filter(item -> item.getId().equals(this.id)).findAny().orElse(null);
if (old != null) {
oldParent.getChildren().remove(old);
}
this.parent = null;
return this;
}
if (parent.equals(this.parent)) {
return this;
}
this.parent = parent;
parent.getChildren().add(this);
return this;
}
/**
* 메뉴 기본 설정 저장
*
* @param updateRequestDto
* @return
*/
public Menu updateDetail(MenuUpdateRequestDto updateRequestDto) {
this.menuKorName = updateRequestDto.getMenuKorName();
this.menuEngName = updateRequestDto.getMenuEngName();
this.menuType = updateRequestDto.getMenuType();
this.connectId = updateRequestDto.getConnectId();
this.urlPath = updateRequestDto.getUrlPath();
this.isUse = updateRequestDto.getIsUse();
this.isShow = updateRequestDto.getIsShow();
this.isBlank = updateRequestDto.getIsBlank();
this.subName = updateRequestDto.getSubName();
this.description = updateRequestDto.getDescription();
this.icon = updateRequestDto.getIcon();
return this;
}
/**
* 부모 메뉴 설정 및 양방향 관계 처리
*
* @param parent
*/
public void setParentMenu(Menu parent) {
this.parent = parent;
parent.getChildren().add(this);
}
/**
* 연관관계 데이터(권한별 메뉴) 조회
*
* @param roleId
* @return
*/
public MenuRole getMenuRole(String roleId) {
return this.getMenuRoles()
.stream()
.filter(menuRole ->
menuRole.getRoleId().equals(roleId))
.findAny().orElse(null);
}
}

View File

@@ -0,0 +1,23 @@
package org.egovframe.cloud.portalservice.domain.menu;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRepository
* <p>
* 메뉴관리 > Menu 엔티티를 위한 Repository
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
public interface MenuRepository extends JpaRepository<Menu, Long>, MenuRepositoryCustom {
}

View File

@@ -0,0 +1,28 @@
package org.egovframe.cloud.portalservice.domain.menu;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuTreeResponseDto;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRepositoryCustom
* <p>
* 메뉴관리 > Menu querydsl interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
public interface MenuRepositoryCustom {
List<MenuTreeResponseDto> findTreeBySiteId(Long siteId);
MenuResponseDto findByIdWithConnectName(Long menuId);
}

View File

@@ -0,0 +1,108 @@
package org.egovframe.cloud.portalservice.domain.menu;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuTreeResponseDto;
import org.egovframe.cloud.portalservice.domain.board.QBoard;
import org.egovframe.cloud.portalservice.domain.content.QContent;
import org.egovframe.cloud.portalservice.domain.user.QUser;
import java.util.List;
import static com.querydsl.core.types.Projections.constructor;
import static com.querydsl.core.types.Projections.fields;
import static org.egovframe.cloud.portalservice.domain.board.QBoard.board;
import static org.egovframe.cloud.portalservice.domain.content.QContent.content;
import static org.egovframe.cloud.portalservice.domain.menu.QMenu.menu;
import static org.egovframe.cloud.portalservice.domain.message.QMessage.message;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRepositoryImpl
* <p>
* 메뉴관리 > Menu querydsl 구현체
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@RequiredArgsConstructor
public class MenuRepositoryImpl implements MenuRepositoryCustom {
private final JPAQueryFactory jpaQueryFactory;
/**
* 메뉴관리 tree 조회
*
* @param siteId
* @return
*/
@Override
public List<MenuTreeResponseDto> findTreeBySiteId(Long siteId) {
return jpaQueryFactory.select(
constructor(MenuTreeResponseDto.class, menu))
.from(menu)
.where(menu.site.id.eq(siteId), menu.parent.isNull())
.orderBy(menu.sortSeq.asc())
.fetch();
}
/**
* 메뉴 상세 정보 조회
*
* @param menuId
* @return
*/
@Override
public MenuResponseDto findByIdWithConnectName(Long menuId) {
return jpaQueryFactory.select(
fields(MenuResponseDto.class,
menu.id.as("menuId"),
menu.menuKorName,
menu.menuEngName,
menu.menuType,
menu.connectId,
new CaseBuilder()
.when(
menu.menuType.eq("contents")
).then(
JPAExpressions.select(content.contentName)
.from(content)
.where(content.contentNo.eq(menu.connectId)))
.when(
menu.menuType.eq("board")
).then(
JPAExpressions.select(board.boardName)
.from(board)
.where(board.boardNo.eq(menu.connectId)))
.otherwise("").as("connectName"),
menu.urlPath,
menu.isUse,
menu.isShow,
menu.isBlank,
menu.subName,
menu.description,
menu.icon
)
)
.from(menu)
.where(menu.id.eq(menuId))
.fetchOne();
}
}

View File

@@ -0,0 +1,64 @@
package org.egovframe.cloud.portalservice.domain.menu;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.*;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRole
* <p>
* 메뉴관리 > 권한별 메뉴 도메인 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/12 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
@Entity
public class MenuRole extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menu_role_id")
private Long id; // id
@Column(nullable = false, length = 20)
private String roleId; //role id
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "menu_id")
private Menu menu; //menu
@Builder
public MenuRole(Long id, String roleId, Menu menu) {
this.id = id;
this.roleId = roleId;
this.menu = menu;
}
/**
* 연관관계 설정
*
* @param menu
*/
public void setMenu(Menu menu) {
this.menu = menu;
menu.getMenuRoles().add(this);
}
}

View File

@@ -0,0 +1,23 @@
package org.egovframe.cloud.portalservice.domain.menu;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRoleRepository
* <p>
* 메뉴관리 > 권한별 메뉴 Repository interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/12 shinmj 최초 생성
* </pre>
*/
public interface MenuRoleRepository extends JpaRepository<MenuRole, Long>, MenuRoleRepositoryCustom {
}

View File

@@ -0,0 +1,29 @@
package org.egovframe.cloud.portalservice.domain.menu;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuSideResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuTreeResponseDto;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRoleRepositoryCustom
* <p>
* 메뉴관리 > 권한별 메뉴 querydsl interface
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/12 shinmj 최초 생성
* </pre>
*/
public interface MenuRoleRepositoryCustom {
List<MenuRoleResponseDto> findTree(String roleId, Long siteId);
List<MenuSideResponseDto> findMenu(String roleId, Long siteId);
}

View File

@@ -0,0 +1,67 @@
package org.egovframe.cloud.portalservice.domain.menu;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuRoleResponseDto;
import org.egovframe.cloud.portalservice.api.menu.dto.MenuSideResponseDto;
import java.util.List;
import static org.egovframe.cloud.portalservice.domain.menu.QMenu.menu;
/**
* org.egovframe.cloud.portalservice.domain.menu.MenuRoleRepositoryImpl
* <p>
* 메뉴관리 > 권한별 메뉴 querydsl 구현체
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/08/12
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/08/12 shinmj 최초 생성
* </pre>
*/
@RequiredArgsConstructor
public class MenuRoleRepositoryImpl implements MenuRoleRepositoryCustom{
private final JPAQueryFactory jpaQueryFactory;
/**
* 권한별 메뉴 트리 조회
*
* @param roleId
* @param siteId
* @return
*/
@Override
public List<MenuRoleResponseDto> findTree(String roleId, Long siteId) {
return jpaQueryFactory.select(
Projections.constructor(MenuRoleResponseDto.class, menu, Expressions.constant(roleId)))
.from(menu)
.where(menu.site.id.eq(siteId), menu.parent.isNull())
.orderBy(menu.sortSeq.asc())
.fetch();
}
@Override
public List<MenuSideResponseDto> findMenu(String roleId, Long siteId) {
return jpaQueryFactory.select(
Projections.constructor(MenuSideResponseDto.class, menu, Expressions.constant(roleId)))
.from(menu)
.where(menu.site.id.eq(siteId),
menu.parent.isNull(),
menu.menuRoles.any().roleId.eq(roleId),
menu.isUse.isTrue())
.orderBy(menu.sortSeq.asc())
.fetch();
}
}

View File

@@ -0,0 +1,54 @@
package org.egovframe.cloud.portalservice.domain.menu;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.*;
/**
* org.egovframe.cloud.portalservice.domain.menu.Site
* <p>
* 메뉴관리 > 사이트 도메인 class
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@ToString
@Entity
public class Site extends BaseEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "site_id")
private Long id;
@Column(name = "site_name", length = 50)
private String name;
@Column(name = "use_at", columnDefinition = "boolean default true")
private Boolean isUse;
@Column(columnDefinition = "SMALLINT(3)")
private Integer sortSeq;
@Builder
public Site(String name, Boolean isUse, Integer sortSeq) {
this.name = name;
this.isUse = isUse;
this.sortSeq = sortSeq;
}
}

View File

@@ -0,0 +1,27 @@
package org.egovframe.cloud.portalservice.domain.menu;
import org.egovframe.cloud.portalservice.api.menu.dto.SiteResponseDto;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* org.egovframe.cloud.portalservice.domain.menu.SiteRepository
* <p>
* 메뉴관리 > Site 도메인 Repository
*
* @author 표준프레임워크센터 shinmj
* @version 1.0
* @since 2021/07/21
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/21 shinmj 최초 생성
* </pre>
*/
public interface SiteRepository extends JpaRepository<Site, Long> {
List<SiteResponseDto> findAllByIsUseTrueOrderBySortSeq();
}

View File

@@ -0,0 +1,54 @@
package org.egovframe.cloud.portalservice.domain.message;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.servlet.domain.BaseEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* org.egovframe.cloud.portalservice.domain.message.Message
* <p>
* 메시지 엔티티
* Spring MessageSouce 데이터 관리
*
* @author 표준프레임워크센터 jaeyeolkim
* @version 1.0
* @since 2021/07/22
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2021/07/22 jaeyeolkim 최초 생성
* </pre>
*/
@Getter
@NoArgsConstructor
@Entity
public class Message extends BaseEntity {
@Id
private String messageId;
@Column(nullable = false, length = 2000)
private String messageKoName; // 한글명
@Column(length = 2000)
private String messageEnName; // 영문명
@Column(length = 500)
private String messageDescription; // 메시지 설명
@Builder
public Message(String messageId, String messageKoName, String messageEnName, String messageDescription) {
this.messageId = messageId;
this.messageKoName = messageKoName;
this.messageEnName = messageEnName;
this.messageDescription = messageDescription;
}
}

Some files were not shown because too many files have changed in this diff Show More