From 5e4ecf1b928edf3626b2ee0f6da3628ea8f710c6 Mon Sep 17 00:00:00 2001 From: jeonghoon Date: Thu, 9 Mar 2023 23:30:04 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=ED=91=B8=EC=8B=9C=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workit/.gitignore | 3 +- workit/build.gradle | 4 + .../java/workit/auth/ScheduledConfig.java | 18 +++++ .../java/workit/dto/firebase/FcmMessage.java | 30 ++++++++ .../java/workit/service/PushAlarmService.java | 76 +++++++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 workit/src/main/java/workit/auth/ScheduledConfig.java create mode 100644 workit/src/main/java/workit/dto/firebase/FcmMessage.java create mode 100644 workit/src/main/java/workit/service/PushAlarmService.java diff --git a/workit/.gitignore b/workit/.gitignore index d2b3c00..a995b89 100644 --- a/workit/.gitignore +++ b/workit/.gitignore @@ -36,4 +36,5 @@ out/ ### VS Code ### .vscode/ -src/main/resources/application.yml \ No newline at end of file +src/main/resources/application.yml +src/main/resources/firebase-adminsdk.json \ No newline at end of file diff --git a/workit/build.gradle b/workit/build.gradle index b3dbb92..1f3a04f 100644 --- a/workit/build.gradle +++ b/workit/build.gradle @@ -25,6 +25,10 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + // firebase + implementation 'com.google.firebase:firebase-admin:9.1.1' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:3.1.5' implementation 'com.google.code.gson:gson:2.10' diff --git a/workit/src/main/java/workit/auth/ScheduledConfig.java b/workit/src/main/java/workit/auth/ScheduledConfig.java new file mode 100644 index 0000000..c72fdc2 --- /dev/null +++ b/workit/src/main/java/workit/auth/ScheduledConfig.java @@ -0,0 +1,18 @@ +package workit.auth; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +@Configuration +@EnableScheduling +public class ScheduledConfig { + + public TaskScheduler scheduler() { + ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + int poolSize = 10; + scheduler.setPoolSize(poolSize); + return scheduler; + } +} diff --git a/workit/src/main/java/workit/dto/firebase/FcmMessage.java b/workit/src/main/java/workit/dto/firebase/FcmMessage.java new file mode 100644 index 0000000..d06cb5e --- /dev/null +++ b/workit/src/main/java/workit/dto/firebase/FcmMessage.java @@ -0,0 +1,30 @@ +package workit.dto.firebase; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Builder +@AllArgsConstructor +@Getter +public class FcmMessage { + private boolean validateOnly; + private Message message; + + @Builder + @AllArgsConstructor + @Getter + public static class Message { + private Notification notification; + private String token; + } + + @Builder + @AllArgsConstructor + @Getter + public static class Notification { + private String title; + private String body; + private String image; + } +} diff --git a/workit/src/main/java/workit/service/PushAlarmService.java b/workit/src/main/java/workit/service/PushAlarmService.java new file mode 100644 index 0000000..9c71aa3 --- /dev/null +++ b/workit/src/main/java/workit/service/PushAlarmService.java @@ -0,0 +1,76 @@ +package workit.service; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.util.Arrays; + +@Slf4j +@Service +public class PushAlarmService { + + @Value("${fcm.key.path}") + private String FCM_PRIVATE_KEY_PATH; + + // 메시징만 권한 설정 + @Value("${fcm.key.scope}") + private String FIREBASE_SCOPE; + + @Value("${fcm.key.url}") + private String API_URL; + + private FirebaseMessaging instance; + + @PostConstruct + public void firebaseSetting() throws IOException { + GoogleCredentials googleCredentials = GoogleCredentials + .fromStream(new ClassPathResource(FCM_PRIVATE_KEY_PATH).getInputStream()) + .createScoped((Arrays.asList(FIREBASE_SCOPE))); + FirebaseOptions secondaryAppConfig = FirebaseOptions.builder() + .setCredentials(googleCredentials) + .build(); + FirebaseApp app = FirebaseApp.initializeApp(secondaryAppConfig); + this.instance = FirebaseMessaging.getInstance(app); + } + + @Scheduled(cron = "0 0 09 * * ?") + public void pushMorningDietAlarm() throws FirebaseMessagingException { + log.info("아침 식사 알림"); + pushAlarm("워킷 메시지", "오늘도 화이팅!"); + } + + private void pushAlarm(String title, String body) throws FirebaseMessagingException { + Message message = getMessage(title, body); + sendMessage(message); + } + + private Message getMessage(String title, String body) { + Notification notification = Notification + .builder() + .setTitle(title) + .setBody(body) + .build(); + Message.Builder builder = Message.builder(); + Message message = builder + .setTopic(API_URL) + .setNotification(notification) + .build(); + return message; + } + + public String sendMessage(Message message) throws FirebaseMessagingException { + return this.instance.send(message); + } +} From 1a84394af18092eae9b8c8556266ba6ac056830d Mon Sep 17 00:00:00 2001 From: jeonghoon Date: Sun, 19 Mar 2023 16:09:53 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=EB=82=A0=EC=A7=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workit/src/main/java/workit/service/WorkService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/workit/src/main/java/workit/service/WorkService.java b/workit/src/main/java/workit/service/WorkService.java index 4b61658..8c5898b 100644 --- a/workit/src/main/java/workit/service/WorkService.java +++ b/workit/src/main/java/workit/service/WorkService.java @@ -36,7 +36,6 @@ public AllWorkResponseDto getWorksByDateFilter(Long userId, String start, String SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date startDate = simpleDateFormat.parse(start); Date endDate = simpleDateFormat.parse(end); - Calendar calendar = Calendar.getInstance(); calendar.setTime(endDate); calendar.add(Calendar.DATE, 1); @@ -47,8 +46,8 @@ public AllWorkResponseDto getWorksByDateFilter(Long userId, String start, String List workResponseDtos = new ArrayList<>(); projects.forEach(project -> { workRepository.findByProject(project).stream() - .filter(work -> work.getDate().equals(startDate) || work.getDate().after(startDate)) - .filter(work -> work.getDate().equals(finalEndDate) || work.getDate().before(finalEndDate)) + .filter(work -> !work.getDate().before(startDate)) + .filter(work -> !work.getDate().after(finalEndDate)) .forEach(work -> { WorkResponseDto workResponseDto = new WorkResponseDto(work); workResponseDtos.add(workResponseDto); From fe1683c18fdda82877d1f0619f57d357d4733c24 Mon Sep 17 00:00:00 2001 From: jeonghoon Date: Mon, 3 Apr 2023 16:08:52 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=EC=9B=8C=ED=82=B7=20id?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workit/dto/work/WorkCreateRequestDto.java | 2 +- .../workit/dto/work/WorkDetailResponseDto.java | 16 ++++++++++++++-- .../main/java/workit/service/WorkService.java | 17 +++++------------ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/workit/src/main/java/workit/dto/work/WorkCreateRequestDto.java b/workit/src/main/java/workit/dto/work/WorkCreateRequestDto.java index bd1295a..74cfcdf 100644 --- a/workit/src/main/java/workit/dto/work/WorkCreateRequestDto.java +++ b/workit/src/main/java/workit/dto/work/WorkCreateRequestDto.java @@ -15,7 +15,7 @@ public class WorkCreateRequestDto { @NotNull private Date date; @NotNull - private String projectTitle; + private Long projectId; @NotNull private String workTitle; @NotNull diff --git a/workit/src/main/java/workit/dto/work/WorkDetailResponseDto.java b/workit/src/main/java/workit/dto/work/WorkDetailResponseDto.java index 755a6bf..3c48282 100644 --- a/workit/src/main/java/workit/dto/work/WorkDetailResponseDto.java +++ b/workit/src/main/java/workit/dto/work/WorkDetailResponseDto.java @@ -2,6 +2,7 @@ import lombok.Data; import workit.dto.ability.AbilityInfo; +import workit.entity.Project; import workit.entity.Work; import java.util.Date; @@ -11,7 +12,7 @@ @Data public class WorkDetailResponseDto { private Long workId; - private String projectTitle; + private Project project; private String workTitle; private String description; private Date date; @@ -19,7 +20,7 @@ public class WorkDetailResponseDto { public WorkDetailResponseDto(Work work) { this.workId = work.getId(); - this.projectTitle = work.getProject().getTitle(); + this.project = new Project(work.getProject()); this.workTitle = work.getTitle(); this.description = work.getDescription(); this.date = work.getDate(); @@ -27,4 +28,15 @@ public WorkDetailResponseDto(Work work) { .map(workAbility -> new AbilityInfo(workAbility.getAbility())) .collect(Collectors.toList()); } + + @Data + private static class Project { + private Long projectId; + private String projectTitle; + + public Project(final workit.entity.Project project) { + this.projectId = project.getId(); + this.projectTitle = project.getTitle(); + } + } } diff --git a/workit/src/main/java/workit/service/WorkService.java b/workit/src/main/java/workit/service/WorkService.java index 8c5898b..f91f55a 100644 --- a/workit/src/main/java/workit/service/WorkService.java +++ b/workit/src/main/java/workit/service/WorkService.java @@ -94,15 +94,13 @@ public WorkDetailResponseDto createWork(WorkCreateRequestDto request, Long userI () -> new CustomException(ResponseCode.USER_NOT_FOUND) ); - Project project = getProject(user, request.getProjectTitle()); + Project project = getProject(user, request.getProjectId()); if (request.getAbilities().isEmpty()) { throw new CustomException(ResponseCode.NO_ABILITIES); } validateWorkDescriptionLength(request.getDescription()); - - validateProjectTitleLength(request.getProjectTitle()); validateWorkTitleLength(request.getWorkTitle()); Work work = new Work(); @@ -129,13 +127,12 @@ public WorkDetailResponseDto modifyWork(WorkCreateRequestDto request, Long workI ); validateUsersWork(work, user); - Project project = getProject(user, request.getProjectTitle()); + Project project = getProject(user, request.getProjectId()); if (request.getAbilities().isEmpty()) { throw new CustomException(ResponseCode.NO_ABILITIES); } - validateProjectTitleLength(request.getProjectTitle()); validateWorkTitleLength(request.getWorkTitle()); WorkRequestDto workRequestDto = new WorkRequestDto( @@ -164,13 +161,9 @@ public void deleteWork(Long workId, Long userId) { workRepository.delete(work); } - private Project getProject(User user, String projectTitle) { - return projectRepository.findByUserAndTitle(user, projectTitle) - .orElseGet(() -> { - Project proj = new Project(user, projectTitle); - projectRepository.save(proj); - return proj; - }); + private Project getProject(User user, Long projectId) { + return projectRepository.findByUserIdAndId(user.getId(), projectId) + .orElseThrow(() -> new CustomException(ResponseCode.PROJECT_NOT_FOUND)); } private List makeWorkAbilities(Work work, List abilities) {