diff --git a/build.gradle b/build.gradle index 26be4b9..af6a14f 100644 --- a/build.gradle +++ b/build.gradle @@ -150,11 +150,11 @@ compileJava { } processResources { - exclude { details -> - details.file.name.startsWith('application-') && - details.file.name.endsWith('.yml') && - !(details.file.name in ['application-stage.yml', 'application-prod.yml']) - } +// exclude { details -> +// details.file.name.startsWith('application-') && +// details.file.name.endsWith('.yml') && +// !(details.file.name in ['application-stage.yml', 'application-prod.yml']) +// } } test { diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/IncidentAffectedApiDTO.java b/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/IncidentAffectedApiDTO.java new file mode 100644 index 0000000..30bcd8b --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/IncidentAffectedApiDTO.java @@ -0,0 +1,13 @@ +package com.eactive.apim.portal.apps.community.notice.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IncidentAffectedApiDTO { + private String apiId; + private String apiName; +} diff --git a/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/PortalNoticeDTO.java b/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/PortalNoticeDTO.java index 450f195..41aa940 100644 --- a/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/PortalNoticeDTO.java +++ b/src/main/java/com/eactive/apim/portal/apps/community/notice/dto/PortalNoticeDTO.java @@ -8,11 +8,18 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor public class PortalNoticeDTO { + + public static final String NOTICE_TYPE_NORMAL = "1"; + public static final String NOTICE_TYPE_MAINTENANCE = "2"; + public static final String NOTICE_TYPE_INCIDENT = "3"; + private String id; @NotEmpty(message = "제목을 입력해주세요.") @@ -29,9 +36,33 @@ public class PortalNoticeDTO { private boolean useYn; + private String fixYn; + + private String noticeType; + private String inquirerName; private LocalDateTime createdDate; private LocalDateTime lastModifiedDate; + + // ───── 장애/점검 연동 필드 ───── + private String summary; + private LocalDateTime startedAt; + private LocalDateTime endAt; + private String state; + private String previousState; + private List affectedApis = Collections.emptyList(); + + public boolean isIncidentType() { + return NOTICE_TYPE_INCIDENT.equals(noticeType); + } + + public boolean isMaintenanceType() { + return NOTICE_TYPE_MAINTENANCE.equals(noticeType); + } + + public boolean isIncidentOrMaintenance() { + return isIncidentType() || isMaintenanceType(); + } } \ No newline at end of file diff --git a/src/main/java/com/eactive/apim/portal/apps/community/notice/service/PortalNoticeFacadeImpl.java b/src/main/java/com/eactive/apim/portal/apps/community/notice/service/PortalNoticeFacadeImpl.java index 1a8f6f0..fe8db9c 100644 --- a/src/main/java/com/eactive/apim/portal/apps/community/notice/service/PortalNoticeFacadeImpl.java +++ b/src/main/java/com/eactive/apim/portal/apps/community/notice/service/PortalNoticeFacadeImpl.java @@ -1,8 +1,12 @@ package com.eactive.apim.portal.apps.community.notice.service; +import com.eactive.apim.portal.apps.community.notice.dto.IncidentAffectedApiDTO; import com.eactive.apim.portal.apps.community.notice.dto.PortalNoticeDTO; import com.eactive.apim.portal.apps.community.notice.dto.PortalNoticeSearch; import com.eactive.apim.portal.apps.community.notice.mapper.PortalNoticeMapper; +import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncident; +import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentApiRepository; +import com.eactive.apim.portal.djb.apistatus.incident.repository.DjbApistatusIncidentRepository; import com.eactive.apim.portal.portalNotice.entity.PortalNotice; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -12,7 +16,10 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; +import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; @Service("portalNoticeFacade") @RequiredArgsConstructor @@ -20,12 +27,13 @@ public class PortalNoticeFacadeImpl implements PortalNoticeFacade { private final PortalNoticeService portalNoticeService; private final PortalNoticeMapper portalNoticeMapper; + private final DjbApistatusIncidentRepository incidentRepository; + private final DjbApistatusIncidentApiRepository incidentApiRepository; @Override public List getLatestNotices() { PortalNoticeSearch search = new PortalNoticeSearch(); Pageable pageable = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "createdDate")); -// Pageable pageable = Pageable.ofSize(3); Page notices = getNotices(search, pageable); return notices.getContent(); } @@ -36,13 +44,47 @@ public class PortalNoticeFacadeImpl implements PortalNoticeFacade { Specification spec = Specification.where(search.buildSpecification()) .and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("useYn"),"Y")); - Page noticesPage = portalNoticeService.getNotices(spec, pageable); + // 상단고정(fixYn='Y') 우선 정렬 — 호출자의 sort 앞에 결합 (admin Service 와 일관) + Sort fixYnFirst = Sort.by(Sort.Direction.DESC, "fixYn"); + Pageable fixedPageable = PageRequest.of( + pageable.getPageNumber(), + pageable.getPageSize(), + fixYnFirst.and(pageable.getSort()) + ); + + Page noticesPage = portalNoticeService.getNotices(spec, fixedPageable); return noticesPage.map(portalNoticeMapper::map); } @Override public PortalNoticeDTO getNotice(String id) { PortalNotice portalNotice = portalNoticeService.getNotice(id); - return portalNoticeMapper.map(portalNotice); + PortalNoticeDTO dto = portalNoticeMapper.map(portalNotice); + populateIncident(dto); + return dto; + } + + private void populateIncident(PortalNoticeDTO dto) { + if (!dto.isIncidentOrMaintenance()) { + dto.setAffectedApis(Collections.emptyList()); + return; + } + Optional incidentOpt = incidentRepository.findByNoticeId(dto.getId()); + if (!incidentOpt.isPresent()) { + dto.setAffectedApis(Collections.emptyList()); + return; + } + DjbApistatusIncident incident = incidentOpt.get(); + dto.setSummary(incident.getSummary()); + dto.setStartedAt(incident.getStartedAt()); + dto.setEndAt(incident.getEndAt()); + dto.setState(incident.getState() == null ? null : incident.getState().name()); + dto.setPreviousState(incident.getPreviousState() == null ? null : incident.getPreviousState().name()); + + List apis = incidentApiRepository + .findByIncidentIdOrderByApiId(incident.getIncidentId()).stream() + .map(api -> new IncidentAffectedApiDTO(api.getApiId(), api.getApiName())) + .collect(Collectors.toList()); + dto.setAffectedApis(apis); } } diff --git a/src/main/resources/templates/views/apps/community/mainNoticeDetail.html b/src/main/resources/templates/views/apps/community/mainNoticeDetail.html index 30ec22d..dfa1066 100644 --- a/src/main/resources/templates/views/apps/community/mainNoticeDetail.html +++ b/src/main/resources/templates/views/apps/community/mainNoticeDetail.html @@ -15,10 +15,50 @@
-

개인정보처리 방침 정정 공지

+

+ 장애 + 점검 + 개인정보처리 방침 정정 공지 +

2025.11.01
+ +
+ + + + + + + + + + + + + + + + + + +
시작-종료-
상태-
영향 API +
    +
  • + API_ID + +
  • +
+
+
+
diff --git a/src/main/resources/templates/views/apps/community/mainNoticeList.html b/src/main/resources/templates/views/apps/community/mainNoticeList.html index 023f597..b030a72 100644 --- a/src/main/resources/templates/views/apps/community/mainNoticeList.html +++ b/src/main/resources/templates/views/apps/community/mainNoticeList.html @@ -58,6 +58,15 @@