Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

[#70] 배달 매칭 서비스 #69

Open
wants to merge 18 commits into
base: rider_info_service
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/com/delfood/FoodDeliveryApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
Expand All @@ -24,6 +25,7 @@
@EnableAspectJAutoProxy // 최상위 클래스에 적용해야 AOP를 찾을 수 있도록 만들어준다.
@EnableCaching // Spring에서 Caching을 사용하겠다고 선언한다.
@EnableAsync // 메서드를 비동기 방식으로 실행할 수 있도록 설정한다.
@EnableScheduling // 스케줄링을 허용한다.
public class FoodDeliveryApplication {

public static void main(String[] args) {
Expand Down
162 changes: 160 additions & 2 deletions src/main/java/com/delfood/controller/RiderController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
package com.delfood.controller;

import com.delfood.aop.LoginCheck;
import com.delfood.aop.OwnerShopCheck;
import com.delfood.aop.LoginCheck.UserType;
import com.delfood.aop.RiderLoginCheck;
import com.delfood.dto.rider.AcceptDeliveryRequestDTO;
import com.delfood.dto.rider.DeliveryRiderDTO;
import com.delfood.dto.rider.AcceptDeliveryRequestDTO.RequestResult;
import com.delfood.dto.rider.DeliveryInfoDTO;
import com.delfood.dto.rider.DeliveryOrderInfo;
import com.delfood.dto.rider.RiderDTO;
import com.delfood.error.exception.DuplicateException;
import com.delfood.error.exception.TargetNotFoundException;
import com.delfood.service.OrderService;
import com.delfood.service.delivery.DeliveryService;
import com.delfood.service.rider.RiderInfoService;
import com.delfood.utils.SessionUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import javax.servlet.http.HttpSession;
import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.log4j.Log4j2;
Expand All @@ -21,6 +34,7 @@
import org.springframework.web.bind.annotation.PatchMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
Expand All @@ -37,6 +51,12 @@ public class RiderController {
@Autowired
private ObjectMapper objectMapper;

@Autowired
private DeliveryService deliveryService;

@Autowired
private OrderService orderService;

/**
* 아이디 중복 체크.
* @author jun
Expand Down Expand Up @@ -123,14 +143,123 @@ public void deleteRiderAccount(HttpSession session, String password) {
SessionUtil.logoutRider(session);
}

/**
* 라이더의 메일 주소를 변경한다.
* @param session 현제 세션
* @param request 요청 정보
*/
@PatchMapping("mail")
public void updateMail(HttpSession session, @RequestBody UpdateMailRequest request) {
String id = SessionUtil.getLoginRiderId(session);
riderInfoService.changeMail(id, request.getPassword(), request.getUpdateMail());
}

/**
* 주문에 대한 배달 매칭 요청을 진행한다.
* @param request 요청 정보
* @param session 현재 세션
* @return
*/
@PostMapping("delivery/accept")
@LoginCheck(type = UserType.RIDER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모습을 보니 떠오른건데 type보다는 level이 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

level도 생각해보았는데 뭔가 접근의 계층이 있어야 할것같은 느낌이라서요. 제가 만든 로그인은 3가지의 전혀 다른 타입이라서 일단 타입으로 해두었습니다.

public AcceptDeliveryRequestDTO deliveryAccept(@RequestBody DeliveryAcceptRequest request,
HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
return deliveryService.acceptDeliveryRequest(riderId, request.getOrderId());
}


/**
* 해당 주문의 배달을 완료했다는 요청을 받는다.
* @author jun
* @param request 요청 정보
* @param session 현제 세션
*/
@PatchMapping("delivery/complete")
@LoginCheck(type = UserType.RIDER)
public void deliveryComplete(@RequestBody DeliveryCompleteRequest request, HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
if (deliveryService.isRiderOrder(riderId, request.getOrderId()) == false) {
log.info("주문 완료 권한 없음. 주문 아이디 : {}, 라이더 아이디 : {}", request.getOrderId(), riderId);
throw new IllegalArgumentException("해당 라이더가 배달중인 주문이 아닙니다. 권한이 없습니다.");
}
deliveryService.deliveryComplete(request.getOrderId());
}

/**
* 라이더의 현제 위치 정보를 업데이트한다.
* 새로운 정보를 덧씌우는 것이기 때문에 put으로 매핑하였다.
* @author jun
* @param info 요청 정보
* @param session 현재 세션
*/
@PutMapping("delivery/available")
@LoginCheck(type = UserType.RIDER)
public void updateDeliveryRiderInfo(DeliveryRiderDTO info, HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);

if (riderInfoService.hasDelivery(riderId)) {
throw new DuplicateException("이미 진행중인 배달이 있습니다. 한번에 하나의 배달만 가능합니다.");
}

deliveryService.updateRider(info);
}

/**
* 라이더를 배당 매칭 대기 명단에서 제거한다.
* @author jun
* @param session 현재 세션
*/
@DeleteMapping("delivery/available")
@LoginCheck(type = UserType.RIDER)
public void deletDeliveryRiderInfo(HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
deliveryService.delete(riderId);
}

/**
* 라이더의 모든 배달 현황을 확인한다.
* @param session 현제 세션
* @return
*/
@GetMapping("delivery")
@LoginCheck(type = UserType.RIDER)
public List<DeliveryInfoDTO> getAllDeliveryList(Long lastViewedOrderId, HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
return deliveryService.getMyAllDeliveries(riderId, lastViewedOrderId);
}

/**
* 현재 배달중인 주문 정보를 확인한다.
* @param session 현제 세션
* @return
*/
@GetMapping("delivery/current")
@LoginCheck(type = UserType.RIDER)
public DeliveryInfoDTO getCurrentDelivery(HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
DeliveryInfoDTO currentDelivery = deliveryService.getCurrentDelivery(riderId);
if (Objects.isNull(currentDelivery)) {
throw new TargetNotFoundException("현재 라이더님은 배달중이 아닙니다.");
}
return currentDelivery;
}

/**
* 오늘 배달한 배달료를 조회한다.
* @param session 현제 세션
* @return
*/
@GetMapping("delivery/bills/today")
@LoginCheck(type = UserType.RIDER)
public TodayDeliveryBillsResponse getTodayDeliveyBills(HttpSession session) {
String riderId = SessionUtil.getLoginRiderId(session);
List<DeliveryOrderInfo> todayDeliveryBills = deliveryService.getTodayDeliveryBills(riderId);
return TodayDeliveryBillsResponse.builder()
.deliveries(todayDeliveryBills)
.riderId(riderId)
.build();
}

// Request
@Getter
private static class SignInRequest {
Expand All @@ -140,7 +269,12 @@ private static class SignInRequest {
@NonNull
private String password;
}


@Getter
private static class DeliveryAcceptRequest {
private Long orderId;
}

@Getter
private static class UpdatePasswordRequest {
@NonNull
Expand All @@ -159,6 +293,30 @@ private static class UpdateMailRequest {
private String updateMail;
}

@Getter
private static class DeliveryCompleteRequest {
@NonNull
private Long orderId;
}

@Getter
private static class TodayDeliveryBillsResponse {
private List<DeliveryOrderInfo> deliveries;
private long totalCost;
private String riderId;

@Builder
public TodayDeliveryBillsResponse(@NonNull List<DeliveryOrderInfo> deliveries,
@NonNull String riderId) {
this.deliveries = deliveries;
this.riderId = riderId;
initCost();
}

private void initCost() {
this.totalCost = deliveries.stream().mapToLong(e -> e.getDeliveryCost()).sum();
}
}


}
32 changes: 32 additions & 0 deletions src/main/java/com/delfood/dao/FcmDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class FcmDao {

@Autowired
private ObjectMapper objectMapper;

@Value("#{expire.fcm.rider}")
private static Long riderTokenExpireSecond;

@Value("${expire.fcm.member}")
private static Long memberTokenExpireSecond;
Expand Down Expand Up @@ -85,6 +88,35 @@ public void addOwnerToken(String ownerId, String token) {
}
}

public void addRiderToken(String riderId, String token) {
String key = RedisKeyFactory.generateFcmRiderKey(riderId);
redisTemplate.watch(key);
try {
if (getRiderTokens(riderId).contains(token)) { // 토큰이 이미 있을 경우
return;
}
redisTemplate.multi();

redisTemplate.opsForList().rightPush(key, token);
redisTemplate.expire(key, riderTokenExpireSecond, TimeUnit.SECONDS);

redisTemplate.exec();
} catch (Exception e) {
log.error("Redis Add Rider Token ERROR! key : {}", key);
log.error("ERROR Info : {} ", e.getMessage());
redisTemplate.discard();
throw new RuntimeException(
"Cannot add rider token. key : " + key + ", ERROR Info " + e.getMessage());
}
}

public List<String> getRiderTokens(String riderId) {
return redisTemplate.opsForList().range(RedisKeyFactory.generateFcmRiderKey(riderId), 0, -1)
.stream()
.map(e -> objectMapper.convertValue(e, String.class))
.collect(Collectors.toList());
}

/**
* 해당 고객의 토큰 리스트를 조회한다.
* @author jun
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/delfood/dao/deliveery/DeliveryDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.delfood.dao.deliveery;

import com.delfood.dto.OrderDTO.OrderStatus;
import com.delfood.dto.address.Position;
import com.delfood.dto.rider.DeliveryRiderDTO;
import java.util.List;

public interface DeliveryDao {

void updateRiderInfo(DeliveryRiderDTO riderInfo);

boolean deleteRiderInfo(String riderId);

boolean hasRiderInfo(String riderId);

void deleteNonUpdatedRiders();

DeliveryRiderDTO getRiderInfo(String riderId);

List<DeliveryRiderDTO> getRiderList();

void deleteAll(List<String> idList);

OrderStatus getOrderStatus(Long orderId);

void setOrderStatus(Long orderId, OrderStatus status);

void deleteOrderStatus(Long orderId);
}
Loading