From 234a14a818c06f52462ff19fbac92894472896a1 Mon Sep 17 00:00:00 2001 From: psyeon1120 Date: Fri, 25 Aug 2023 03:06:26 +0900 Subject: [PATCH 1/3] =?UTF-8?q?#139=20feat:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EA=B8=B0=EC=B4=88=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + build.gradle.kts | 4 ++ .../com/psr/psr/notification/dto/Data.kt | 6 +++ .../psr/psr/notification/dto/FcmMessage.kt | 6 +++ .../com/psr/psr/notification/dto/Message.kt | 7 +++ .../psr/psr/notification/dto/NotiAssembler.kt | 48 +++++++++++++++++++ .../psr/psr/notification/dto/Notification.kt | 6 +++ .../notification/entity/NotificationType.kt | 8 ++++ .../{Notification.kt => PushNotification.kt} | 12 +++-- .../repository/NotificationRepository.kt | 4 +- .../repository/NotificationRepositoryImpl.kt | 12 ++--- .../service/NotificationService.kt | 38 ++++++++++++++- .../com/psr/psr/order/dto/OrderAssembler.kt | 2 +- .../com/psr/psr/order/entity/OrderStatus.kt | 15 +++--- .../com/psr/psr/order/service/OrderService.kt | 4 +- .../psr/user/dto/assembler/UserAssembler.kt | 3 +- .../com/psr/psr/user/dto/request/SignUpReq.kt | 1 + .../kotlin/com/psr/psr/user/entity/User.kt | 2 + 18 files changed, 156 insertions(+), 23 deletions(-) create mode 100644 src/main/kotlin/com/psr/psr/notification/dto/Data.kt create mode 100644 src/main/kotlin/com/psr/psr/notification/dto/FcmMessage.kt create mode 100644 src/main/kotlin/com/psr/psr/notification/dto/Message.kt create mode 100644 src/main/kotlin/com/psr/psr/notification/dto/NotiAssembler.kt create mode 100644 src/main/kotlin/com/psr/psr/notification/dto/Notification.kt create mode 100644 src/main/kotlin/com/psr/psr/notification/entity/NotificationType.kt rename src/main/kotlin/com/psr/psr/notification/entity/{Notification.kt => PushNotification.kt} (68%) diff --git a/.gitignore b/.gitignore index 36ee796..c9fd7ab 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build/ !**/src/main/**/build/ !**/src/test/**/build/ application-secret.yaml +firebase-service-key.json ### STS ### .apt_generated diff --git a/build.gradle.kts b/build.gradle.kts index c3ebfcb..3a2a8b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -68,6 +68,10 @@ dependencies { // random implementation("org.apache.commons:commons-lang3:3.12.0") + + // notification + implementation("com.google.firebase:firebase-admin:9.2.0") + implementation("com.squareup.okhttp3:okhttp:4.10.0") } diff --git a/src/main/kotlin/com/psr/psr/notification/dto/Data.kt b/src/main/kotlin/com/psr/psr/notification/dto/Data.kt new file mode 100644 index 0000000..0e1308d --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/dto/Data.kt @@ -0,0 +1,6 @@ +package com.psr.psr.notification.dto + +data class Data( + val relatedId: Long, + val notiType: String +) diff --git a/src/main/kotlin/com/psr/psr/notification/dto/FcmMessage.kt b/src/main/kotlin/com/psr/psr/notification/dto/FcmMessage.kt new file mode 100644 index 0000000..6f393ee --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/dto/FcmMessage.kt @@ -0,0 +1,6 @@ +package com.psr.psr.notification.dto + +data class FcmMessage ( + val validate_only: Boolean, + val message: Message +) diff --git a/src/main/kotlin/com/psr/psr/notification/dto/Message.kt b/src/main/kotlin/com/psr/psr/notification/dto/Message.kt new file mode 100644 index 0000000..d973cf6 --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/dto/Message.kt @@ -0,0 +1,7 @@ +package com.psr.psr.notification.dto + +data class Message( + val notification: Notification, + val token: String, + val data: Data +) diff --git a/src/main/kotlin/com/psr/psr/notification/dto/NotiAssembler.kt b/src/main/kotlin/com/psr/psr/notification/dto/NotiAssembler.kt new file mode 100644 index 0000000..bc5e7ba --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/dto/NotiAssembler.kt @@ -0,0 +1,48 @@ +package com.psr.psr.notification.dto + +import com.psr.psr.notification.entity.NotificationType +import com.psr.psr.notification.entity.PushNotification +import com.psr.psr.user.entity.User +import org.springframework.stereotype.Component + + +@Component +class NotiAssembler { + fun toEntity(receiver: User, title: String, content: String, relatedId: Long, type: NotificationType): PushNotification { + return PushNotification( + user = receiver, + title = title, + content = content, + relatedId = relatedId, + type = type + ) + } + fun toMessageDTO(targetToken: String, title: String, body: String, relatedId: Long, notiType: String): Message { + return Message( + notification = toNotificationDTO(title, body), + token = targetToken, + data = toDataDTO(relatedId, notiType) + ) + } + + fun toNotificationDTO(title: String, body: String): Notification { + return Notification( + title = title, + body = body + ) + } + + fun toDataDTO(relatedId: Long, notiType: String): Data { + return Data( + relatedId = relatedId, + notiType = notiType + ) + } + + fun makeMessage(targetToken: String, title: String, body: String, relatedId: Long, notiType: String): FcmMessage { + return FcmMessage( + validate_only = false, + message = toMessageDTO(targetToken, title, body, relatedId, notiType) + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/psr/psr/notification/dto/Notification.kt b/src/main/kotlin/com/psr/psr/notification/dto/Notification.kt new file mode 100644 index 0000000..81f817a --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/dto/Notification.kt @@ -0,0 +1,6 @@ +package com.psr.psr.notification.dto + +data class Notification( + val title: String, + val body: String +) diff --git a/src/main/kotlin/com/psr/psr/notification/entity/NotificationType.kt b/src/main/kotlin/com/psr/psr/notification/entity/NotificationType.kt new file mode 100644 index 0000000..a17644b --- /dev/null +++ b/src/main/kotlin/com/psr/psr/notification/entity/NotificationType.kt @@ -0,0 +1,8 @@ +package com.psr.psr.notification.entity + +enum class NotificationType { + NEW_ORDER, + CHANGED_ORDER_STATUS, + TWO_MONTH_ORDER, + CHAT +} \ No newline at end of file diff --git a/src/main/kotlin/com/psr/psr/notification/entity/Notification.kt b/src/main/kotlin/com/psr/psr/notification/entity/PushNotification.kt similarity index 68% rename from src/main/kotlin/com/psr/psr/notification/entity/Notification.kt rename to src/main/kotlin/com/psr/psr/notification/entity/PushNotification.kt index e85761f..943c351 100644 --- a/src/main/kotlin/com/psr/psr/notification/entity/Notification.kt +++ b/src/main/kotlin/com/psr/psr/notification/entity/PushNotification.kt @@ -6,9 +6,9 @@ import jakarta.persistence.* import org.jetbrains.annotations.NotNull @Entity -data class Notification( +data class PushNotification( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - var id: Long, + var id: Long? = null, @ManyToOne @JoinColumn(nullable = false, name = "user_id") @@ -19,6 +19,12 @@ data class Notification( var title: String, @NotNull - var content: String + var content: String, + + // 알림의 주체인 요청, 채팅 등의 ID + var relatedId: Long, + + @NotNull + var type: NotificationType ) : BaseEntity() diff --git a/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepository.kt b/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepository.kt index 9a4083b..23c916c 100644 --- a/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepository.kt +++ b/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepository.kt @@ -1,9 +1,9 @@ package com.psr.psr.notification.repository -import com.psr.psr.notification.entity.Notification +import com.psr.psr.notification.entity.PushNotification import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository @Repository -interface NotificationRepository: JpaRepository, NotificationCustom { +interface NotificationRepository: JpaRepository, NotificationCustom { } \ No newline at end of file diff --git a/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepositoryImpl.kt b/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepositoryImpl.kt index c437258..6dd0607 100644 --- a/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepositoryImpl.kt +++ b/src/main/kotlin/com/psr/psr/notification/repository/NotificationRepositoryImpl.kt @@ -2,7 +2,7 @@ package com.psr.psr.notification.repository import com.psr.psr.notification.dto.NotiList import com.psr.psr.notification.dto.NotificationListRes -import com.psr.psr.notification.entity.QNotification.notification +import com.psr.psr.notification.entity.QPushNotification.pushNotification import com.psr.psr.user.entity.User import com.querydsl.core.group.GroupBy.groupBy import com.querydsl.core.group.GroupBy.list @@ -23,19 +23,19 @@ class NotificationRepositoryImpl( override fun findNotificationByUserGroupByDate(user: User, pageable: Pageable): Page { val formattedDate: StringTemplate = Expressions.stringTemplate( "DATE_FORMAT({0}, {1})", - notification.createdAt, + pushNotification.createdAt, ConstantImpl.create("%Y-%m-%d") ) val result = queryFactory - .selectFrom(notification) - .where(notification.user.eq(user)) - .orderBy(notification.id.desc()) + .selectFrom(pushNotification) + .where(pushNotification.user.eq(user)) + .orderBy(pushNotification.id.desc()) .offset(pageable.offset) .limit(pageable.pageSize.toLong()) .transform(groupBy(formattedDate) .list(Projections.constructor(NotificationListRes::class.java, formattedDate, - list(Projections.constructor(NotiList::class.java, notification.title, notification.content))))) + list(Projections.constructor(NotiList::class.java, pushNotification.title, pushNotification.content))))) return PageImpl(result, pageable, result.size.toLong()) } diff --git a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt index 8861a44..0c29682 100644 --- a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt +++ b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt @@ -1,17 +1,53 @@ package com.psr.psr.notification.service +import com.fasterxml.jackson.databind.ObjectMapper +import com.google.auth.oauth2.GoogleCredentials +import com.psr.psr.notification.dto.NotiAssembler import com.psr.psr.notification.dto.NotificationListRes import com.psr.psr.notification.repository.NotificationRepository import com.psr.psr.user.entity.User +import okhttp3.* +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.toRequestBody +import org.springframework.beans.factory.annotation.Value +import org.springframework.core.io.ClassPathResource import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable +import org.springframework.http.HttpHeaders import org.springframework.stereotype.Service @Service class NotificationService( - private val notificationRepository: NotificationRepository + private val notificationRepository: NotificationRepository, + private val notiAssembler: NotiAssembler, + @Value("\${firebase.sendUrl}") private val sendUrl: String, + private val objectMapper: ObjectMapper ) { + // 알림 목록 조회 fun getNotiList(user: User, pageable: Pageable): Page { return notificationRepository.findNotificationByUserGroupByDate(user, pageable) } + + // firebase accessToken 발급 + private fun getAccessToken(): String? { + val firebaseConfigPath = "firebase-service-key.json" + val googleCredentials = GoogleCredentials + .fromStream(ClassPathResource(firebaseConfigPath).inputStream) + .createScoped(listOf("https://www.googleapis.com/auth/cloud-platform")) + googleCredentials.refreshIfExpired() + return googleCredentials.accessToken.tokenValue + } + + // 메세지 전송 + private fun sendMessage(message: String): Response { + val client = OkHttpClient() + val requestBody: RequestBody = message.toRequestBody("application/json; charset=utf-8".toMediaType()) + val request: Request = Request.Builder() + .url(sendUrl) + .post(requestBody) + .addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()) + .addHeader(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8") + .build() + return client.newCall(request).execute() + } } \ No newline at end of file diff --git a/src/main/kotlin/com/psr/psr/order/dto/OrderAssembler.kt b/src/main/kotlin/com/psr/psr/order/dto/OrderAssembler.kt index 98c4fc8..829edc8 100644 --- a/src/main/kotlin/com/psr/psr/order/dto/OrderAssembler.kt +++ b/src/main/kotlin/com/psr/psr/order/dto/OrderAssembler.kt @@ -23,7 +23,7 @@ class OrderAssembler { fun toOrderResDTO(order: Order, isSeller: Boolean): OrderRes { return OrderRes( isSeller = isSeller, - status = order.orderStatus.statusName, + status = order.orderStatus.value, orderUserId = order.user.id!!, orderDate = order.createdAt.format(DateTimeFormatter.ISO_DATE), productId = order.product.id!!, diff --git a/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt b/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt index aac58fa..bac15b2 100644 --- a/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt +++ b/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt @@ -2,16 +2,17 @@ package com.psr.psr.order.entity import com.psr.psr.global.exception.BaseException import com.psr.psr.global.exception.BaseResponseCode +import com.psr.psr.global.resolver.EnumType -enum class OrderStatus(val statusName: String) { - ORDER_WAITING("요청대기"), - PROGRESSING("진행중"), - COMPLETED("진행완료"), - CANCELED("요청취소"); +enum class OrderStatus(override val value: String, val notiSentence: String): EnumType { + ORDER_WAITING("요청대기", "님의 요청을 확인해주세요!"), + PROGRESSING("진행중", "요청이 진행되었습니다"), + COMPLETED("진행완료", "요청이 진행 완료되었습니다"), + CANCELED("요청취소", "요청이 취소되었습니다"); companion object { - fun findByName(statusName: String): OrderStatus { - return OrderStatus.values().find { it.statusName == statusName } + fun findByValue(value: String): OrderStatus { + return enumValues().find { it.value == value } ?: throw BaseException(BaseResponseCode.INVALID_ORDER_STATUS) } } diff --git a/src/main/kotlin/com/psr/psr/order/service/OrderService.kt b/src/main/kotlin/com/psr/psr/order/service/OrderService.kt index ece63a4..f963993 100644 --- a/src/main/kotlin/com/psr/psr/order/service/OrderService.kt +++ b/src/main/kotlin/com/psr/psr/order/service/OrderService.kt @@ -49,7 +49,7 @@ class OrderService( // 요청 목록 조회(요청 상태별) fun getOrderListByOrderStatus(user: User, type: String, status: String, pageable: Pageable): Page { - val orderStatus = OrderStatus.findByName(status) + val orderStatus = OrderStatus.findByValue(status) val orderList: Page = if (type == SELL) orderRepository.findByProductUserAndOrderStatusAndStatus(user, orderStatus, ACTIVE_STATUS, pageable) @@ -65,7 +65,7 @@ class OrderService( if (order.user.id != user.id) throw BaseException(BaseResponseCode.NO_PERMISSION) var orderStatus: OrderStatus? = null - if (status != null) orderStatus = OrderStatus.findByName(status) + if (status != null) orderStatus = OrderStatus.findByValue(status) order.editOrder(orderReq, orderStatus) orderRepository.save(order) diff --git a/src/main/kotlin/com/psr/psr/user/dto/assembler/UserAssembler.kt b/src/main/kotlin/com/psr/psr/user/dto/assembler/UserAssembler.kt index 3e92672..b842131 100644 --- a/src/main/kotlin/com/psr/psr/user/dto/assembler/UserAssembler.kt +++ b/src/main/kotlin/com/psr/psr/user/dto/assembler/UserAssembler.kt @@ -37,7 +37,8 @@ class UserAssembler { marketing = signUpReq.marketing, notification = signUpReq.notification, name = signUpReq.name, - nickname = signUpReq.nickname) + nickname = signUpReq.nickname, + deviceToken = signUpReq.deviceToken) } fun toInterestListEntity(user: User, signUpReq: SignUpReq): List { diff --git a/src/main/kotlin/com/psr/psr/user/dto/request/SignUpReq.kt b/src/main/kotlin/com/psr/psr/user/dto/request/SignUpReq.kt index 508c234..b787c8b 100644 --- a/src/main/kotlin/com/psr/psr/user/dto/request/SignUpReq.kt +++ b/src/main/kotlin/com/psr/psr/user/dto/request/SignUpReq.kt @@ -43,6 +43,7 @@ data class SignUpReq ( val marketing: Boolean, @field:NotNull val notification: Boolean, + val deviceToken: String? = null, @field:NotEmpty val interestList: List, val entreInfo: UserEidReq?= null diff --git a/src/main/kotlin/com/psr/psr/user/entity/User.kt b/src/main/kotlin/com/psr/psr/user/entity/User.kt index 57c2abe..74aa061 100644 --- a/src/main/kotlin/com/psr/psr/user/entity/User.kt +++ b/src/main/kotlin/com/psr/psr/user/entity/User.kt @@ -55,6 +55,8 @@ class User( @NotNull var notification: Boolean, + var deviceToken: String? = null, + @OneToMany(mappedBy = "user") @Where(clause = "status = 'active'") var products: List? = ArrayList(), From 72218e7dd78512c0ecc02d84a0fb59f3df2a11f3 Mon Sep 17 00:00:00 2001 From: psyeon1120 Date: Fri, 25 Aug 2023 03:33:28 +0900 Subject: [PATCH 2/3] =?UTF-8?q?#139=20feat:=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=95=8C=EB=A6=BC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/psr/psr/global/Constant.kt | 7 ++ .../service/NotificationService.kt | 74 +++++++++++++++++++ .../com/psr/psr/order/entity/OrderStatus.kt | 4 +- .../com/psr/psr/order/service/OrderService.kt | 12 ++- 4 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/psr/psr/global/Constant.kt b/src/main/kotlin/com/psr/psr/global/Constant.kt index b09be4c..35ea754 100644 --- a/src/main/kotlin/com/psr/psr/global/Constant.kt +++ b/src/main/kotlin/com/psr/psr/global/Constant.kt @@ -58,4 +58,11 @@ class Constant { const val POPULAR = "인기순" } } + + class NotiSentence{ + companion object NotiSentence{ + const val NEW_ORDER_SENTENCE = "님의 요청을 확인해주세요!" + const val TWO_MONTH_ORDER_SENTENCE = "님의 요청 상태를 확인해주세요!" + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt index 0c29682..8bcb405 100644 --- a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt +++ b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt @@ -2,9 +2,14 @@ package com.psr.psr.notification.service import com.fasterxml.jackson.databind.ObjectMapper import com.google.auth.oauth2.GoogleCredentials +import com.psr.psr.global.Constant.NotiSentence.NotiSentence.NEW_ORDER_SENTENCE +import com.psr.psr.global.Constant.NotiSentence.NotiSentence.TWO_MONTH_ORDER_SENTENCE +import com.psr.psr.notification.dto.FcmMessage import com.psr.psr.notification.dto.NotiAssembler import com.psr.psr.notification.dto.NotificationListRes +import com.psr.psr.notification.entity.NotificationType import com.psr.psr.notification.repository.NotificationRepository +import com.psr.psr.order.entity.OrderStatus import com.psr.psr.user.entity.User import okhttp3.* import okhttp3.MediaType.Companion.toMediaType @@ -28,6 +33,75 @@ class NotificationService( return notificationRepository.findNotificationByUserGroupByDate(user, pageable) } + // 새로운 요청 알림 + fun sendNewOrderNoti(productName: String, orderReceiver: User, ordererName: String, orderId: Long) { + val messageBody = ordererName + NEW_ORDER_SENTENCE + notificationRepository.save(notiAssembler.toEntity( + orderReceiver, + productName, + messageBody, + orderId, + NotificationType.NEW_ORDER + )) + + if (orderReceiver.deviceToken != null) { + val message: FcmMessage = notiAssembler.makeMessage( + orderReceiver.deviceToken!!, + productName, + messageBody, + orderId, + NotificationType.NEW_ORDER.name + ) + sendMessage(objectMapper.writeValueAsString(message)) + } + } + + // 요청 상태 변경 알림 + fun sendChangeOrderStatusNoti(productName: String, orderer: User, orderStatus: OrderStatus, orderId: Long) { + val messageBody = orderStatus.notiSentence!! + notificationRepository.save(notiAssembler.toEntity( + orderer, + productName, + messageBody, + orderId, + NotificationType.CHANGED_ORDER_STATUS + )) + + if (orderer.deviceToken != null) { + val message: FcmMessage = notiAssembler.makeMessage( + orderer.deviceToken!!, + productName, + messageBody, + orderId, + NotificationType.CHANGED_ORDER_STATUS.name + ) + sendMessage(objectMapper.writeValueAsString(message)) + } + } + + // 2달 뒤 요청상태 입력 요망 알림 + fun send2MonthOrderNoti(productName: String, orderer: User, ordererName: String, orderId: Long) { + val messageBody = ordererName + TWO_MONTH_ORDER_SENTENCE + notificationRepository.save(notiAssembler.toEntity( + orderer, + productName, + messageBody, + orderId, + NotificationType.TWO_MONTH_ORDER + )) + + if (orderer.deviceToken != null) { + val message: FcmMessage = notiAssembler.makeMessage( + orderer.deviceToken!!, + productName, + messageBody, + orderId, + NotificationType.TWO_MONTH_ORDER.name + ) + sendMessage(objectMapper.writeValueAsString(message)) + } + } + // firebase accessToken 발급 private fun getAccessToken(): String? { val firebaseConfigPath = "firebase-service-key.json" diff --git a/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt b/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt index bac15b2..e6728e9 100644 --- a/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt +++ b/src/main/kotlin/com/psr/psr/order/entity/OrderStatus.kt @@ -4,8 +4,8 @@ import com.psr.psr.global.exception.BaseException import com.psr.psr.global.exception.BaseResponseCode import com.psr.psr.global.resolver.EnumType -enum class OrderStatus(override val value: String, val notiSentence: String): EnumType { - ORDER_WAITING("요청대기", "님의 요청을 확인해주세요!"), +enum class OrderStatus(override val value: String, val notiSentence: String?): EnumType { + ORDER_WAITING("요청대기", null), PROGRESSING("진행중", "요청이 진행되었습니다"), COMPLETED("진행완료", "요청이 진행 완료되었습니다"), CANCELED("요청취소", "요청이 취소되었습니다"); diff --git a/src/main/kotlin/com/psr/psr/order/service/OrderService.kt b/src/main/kotlin/com/psr/psr/order/service/OrderService.kt index f963993..3626775 100644 --- a/src/main/kotlin/com/psr/psr/order/service/OrderService.kt +++ b/src/main/kotlin/com/psr/psr/order/service/OrderService.kt @@ -4,6 +4,7 @@ import com.psr.psr.global.Constant.OrderType.OrderType.SELL import com.psr.psr.global.Constant.UserStatus.UserStatus.ACTIVE_STATUS import com.psr.psr.global.exception.BaseException import com.psr.psr.global.exception.BaseResponseCode +import com.psr.psr.notification.service.NotificationService import com.psr.psr.order.dto.* import com.psr.psr.order.entity.Order import com.psr.psr.order.entity.OrderStatus @@ -19,13 +20,15 @@ import org.springframework.stereotype.Service class OrderService( private val orderRepository: OrderRepository, private val productRepository: ProductRepository, - private val orderAssembler: OrderAssembler + private val orderAssembler: OrderAssembler, + private val notificationService: NotificationService ) { // 요청하기 fun makeOrder(user: User, orderReq: OrderReq) { val product: Product = orderReq.productId?.let { productRepository.findByIdAndStatus(it, ACTIVE_STATUS) } ?: throw BaseException(BaseResponseCode.NOT_FOUND_PRODUCT) - orderRepository.save(orderAssembler.toEntity(user, orderReq, product)) + val order = orderRepository.save(orderAssembler.toEntity(user, orderReq, product)) + notificationService.sendNewOrderNoti(order.product.name, order.product.user, order.ordererName, order.id!!) } // 요청 상세 조회 @@ -68,6 +71,9 @@ class OrderService( if (status != null) orderStatus = OrderStatus.findByValue(status) order.editOrder(orderReq, orderStatus) - orderRepository.save(order) + val saveOrder = orderRepository.save(order) + + if (status != null) + notificationService.sendChangeOrderStatusNoti(order.product.name, order.product.user, saveOrder.orderStatus, order.id!!) } } \ No newline at end of file From acab8fd8e0e6c95c4aba361c101376643d7b131a Mon Sep 17 00:00:00 2001 From: psyeon1120 Date: Sun, 27 Aug 2023 00:53:42 +0900 Subject: [PATCH 3/3] =?UTF-8?q?#139=20feat:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=88=98=EC=8B=A0=20=EC=97=AC=EB=B6=80=20=EC=B2=B4=ED=81=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../psr/notification/service/NotificationService.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt index 8bcb405..2c8d291 100644 --- a/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt +++ b/src/main/kotlin/com/psr/psr/notification/service/NotificationService.kt @@ -44,7 +44,7 @@ class NotificationService( NotificationType.NEW_ORDER )) - if (orderReceiver.deviceToken != null) { + if (isPushNotiAvailable(orderReceiver)) { val message: FcmMessage = notiAssembler.makeMessage( orderReceiver.deviceToken!!, productName, @@ -67,7 +67,7 @@ class NotificationService( NotificationType.CHANGED_ORDER_STATUS )) - if (orderer.deviceToken != null) { + if (isPushNotiAvailable(orderer)) { val message: FcmMessage = notiAssembler.makeMessage( orderer.deviceToken!!, productName, @@ -90,7 +90,7 @@ class NotificationService( NotificationType.TWO_MONTH_ORDER )) - if (orderer.deviceToken != null) { + if (isPushNotiAvailable(orderer)) { val message: FcmMessage = notiAssembler.makeMessage( orderer.deviceToken!!, productName, @@ -102,6 +102,11 @@ class NotificationService( } } + // 알림 수신 상태 체크 + fun isPushNotiAvailable(user: User): Boolean { + return user.deviceToken != null && user.notification + } + // firebase accessToken 발급 private fun getAccessToken(): String? { val firebaseConfigPath = "firebase-service-key.json"