diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/Mileage.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/Mileage.java index 5352218..3192933 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/Mileage.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/Mileage.java @@ -8,6 +8,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + import java.time.Duration; import java.time.LocalDateTime; @@ -46,6 +48,7 @@ public void addPoints(int pointsToAdd){ this.point += pointsToAdd; } + @Transactional public void startUsage() { if (this.point <= 0) { throw new IllegalStateException("마일리지가 부족하여 사용할 수 없습니다."); diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageController.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageController.java index 3f8440a..865990f 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageController.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageController.java @@ -1,6 +1,7 @@ package com.cagong.receiptpowerserver.domain.mileage; import com.cagong.receiptpowerserver.domain.mileage.dto.*; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -13,6 +14,7 @@ public class MileageController { private final MileageService mileageService; @GetMapping("/total") + @Operation(summary = "전체 마일리지 조회") public ResponseEntity getTotalMileage(){ try { TotalMileageResponse response = mileageService.getTotalMileage(); @@ -23,6 +25,7 @@ public ResponseEntity getTotalMileage(){ } @GetMapping + @Operation(summary = "개별 마일리지 조회") public ResponseEntity getCafeMileage(@RequestParam Long cafeId){ try { CafeMileageResponse response = mileageService.getCafeMileage(cafeId); @@ -33,6 +36,7 @@ public ResponseEntity getCafeMileage(@RequestParam Long caf } @PostMapping + @Operation(summary = "마일리지 적립") public ResponseEntity saveMileage(@RequestBody SaveMileageRequest request){ try { SaveMileageResponse response = mileageService.addMileage(request); @@ -43,16 +47,18 @@ public ResponseEntity saveMileage(@RequestBody SaveMileageR } @PostMapping("/{cafeId}/usage") - public ResponseEntity useMileage(@PathVariable Long cafeId){ + @Operation(summary = "마일리지 사용 시작") + public ResponseEntity useMileage(@PathVariable Long cafeId){ try { - mileageService.startMileageUsage(cafeId); - return ResponseEntity.ok().build(); + UseMileageResponse response = mileageService.startMileageUsage(cafeId); + return ResponseEntity.ok().body(response); } catch (IllegalArgumentException e) { return ResponseEntity.badRequest().build(); } } @PostMapping("/{cafeId}/usage/end") + @Operation(summary = "마일리지 사용 끝") public ResponseEntity endMileage(@PathVariable Long cafeId){ try { EndMileageUsageResponse response = mileageService.endMileageUsage(cafeId); diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageService.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageService.java index d4b7aea..859c212 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageService.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/MileageService.java @@ -5,12 +5,15 @@ import com.cagong.receiptpowerserver.domain.member.Member; import com.cagong.receiptpowerserver.domain.member.MemberRepository; import com.cagong.receiptpowerserver.domain.mileage.dto.*; +import com.cagong.receiptpowerserver.domain.mqtt.MqttService; import com.cagong.receiptpowerserver.global.util.MemberUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @Service @RequiredArgsConstructor @@ -20,9 +23,11 @@ public class MileageService { private final MileageRepository mileageRepository; private final CafeRepository cafeRepository; private final MemberRepository memberRepository; + private final MqttService mqttService; public TotalMileageResponse getTotalMileage(){ Long memberId = MemberUtil.getCurrentMember(); + Member member = memberRepository.findById(memberId) .orElseThrow(() -> new RuntimeException("회원을 찾을 수 없습니다.")); @@ -35,16 +40,19 @@ public TotalMileageResponse getTotalMileage(){ public CafeMileageResponse getCafeMileage(Long cafeId){ Long memberId = MemberUtil.getCurrentMember(); + Member member = memberRepository.findById(memberId) .orElseThrow(() -> new RuntimeException("회원을 찾을 수 없습니다.")); Cafe cafe = cafeRepository.findById(cafeId) .orElseThrow(() -> new RuntimeException("카페를 찾을 수 없습니다.")); - Mileage mileage = mileageRepository.findByMemberAndCafe(member, cafe) - .orElseThrow(() -> new RuntimeException()); + Optional optMileage = mileageRepository.findByMemberAndCafe(member, cafe); + + int mileagePoint = optMileage.map(Mileage::getPoint).orElse(0); + LocalDateTime mileageUpdatedAt = optMileage.map(Mileage::getUpdatedAt).orElse(null); - CafeMileageResponse response = new CafeMileageResponse(cafeId, cafe.getName(), mileage.getPoint(), mileage.getUpdatedAt()); + CafeMileageResponse response = new CafeMileageResponse(cafeId, cafe.getName(), mileagePoint, mileageUpdatedAt); return response; } @@ -57,7 +65,7 @@ public SaveMileageResponse addMileage(SaveMileageRequest request){ Cafe cafe = cafeRepository.findById(request.getCafeId()) .orElseThrow(() -> new RuntimeException("카페를 찾을 수 없습니다.")); - int pointsToAdd = request.getRemainingTime(); + int pointsToAdd = request.getAmount()/25; Mileage mileage = mileageRepository.findByMemberAndCafe(member, cafe) .map(m -> { @@ -76,8 +84,9 @@ public SaveMileageResponse addMileage(SaveMileageRequest request){ } @Transactional - public void startMileageUsage(Long cafeId){ + public UseMileageResponse startMileageUsage(Long cafeId){ Long memberId = MemberUtil.getCurrentMember(); + Member member = memberRepository.findById(memberId) .orElseThrow(() -> new RuntimeException("회원을 찾을 수 없습니다.")); @@ -92,11 +101,18 @@ public void startMileageUsage(Long cafeId){ } catch (IllegalStateException e) { throw new IllegalArgumentException(e.getMessage()); } + + int remainingPoint = mileage.getPoint(); + + mqttService.turnOn(); + mqttService.startTimer(cafe.getId(), remainingPoint); + return new UseMileageResponse(remainingPoint, mileage.getUsageStartTime()); } @Transactional public EndMileageUsageResponse endMileageUsage(Long cafeId){ Long memberId = MemberUtil.getCurrentMember(); + Member member = memberRepository.findById(memberId) .orElseThrow(() -> new RuntimeException("회원을 찾을 수 없습니다.")); @@ -108,6 +124,8 @@ public EndMileageUsageResponse endMileageUsage(Long cafeId){ int remainingMileage = mileage.endUsage(); EndMileageUsageResponse response = new EndMileageUsageResponse(remainingMileage); + + mqttService.turnOff(); return response; } } diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/CafeMileageDto.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/CafeMileageDto.java index fcf8598..eb0065e 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/CafeMileageDto.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/CafeMileageDto.java @@ -7,11 +7,11 @@ public class CafeMileageDto { private Long cafeId; private String cafeName; - private Long totalPoints; + private Long points; - public CafeMileageDto(Long cafeId, String cafeName, Long totalPoints) { + public CafeMileageDto(Long cafeId, String cafeName, Long points) { this.cafeId = cafeId; this.cafeName = cafeName; - this.totalPoints = totalPoints; + this.points = points; } } diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/SaveMileageRequest.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/SaveMileageRequest.java index a7c7b4a..be018f2 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/SaveMileageRequest.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/SaveMileageRequest.java @@ -7,5 +7,5 @@ @AllArgsConstructor public class SaveMileageRequest { private Long cafeId; - private int remainingTime; + private int amount; } diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/TotalMileageResponse.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/TotalMileageResponse.java index 4bdee32..c85bca2 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/TotalMileageResponse.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/TotalMileageResponse.java @@ -9,6 +9,6 @@ @AllArgsConstructor public class TotalMileageResponse { private String username; - private int totalMileage; + private int totalMileagePoints; private List cafeMileageList; } diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/UseMileageResponse.java b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/UseMileageResponse.java new file mode 100644 index 0000000..2a9b34f --- /dev/null +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mileage/dto/UseMileageResponse.java @@ -0,0 +1,13 @@ +package com.cagong.receiptpowerserver.domain.mileage.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@AllArgsConstructor +public class UseMileageResponse { + private int availableMileages; + private LocalDateTime useStartAt; +} diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttController.java b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttController.java index 249eb17..f5ef231 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttController.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttController.java @@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@Profile("!test") + @RestController @RequestMapping("/device") @RequiredArgsConstructor @@ -18,20 +18,19 @@ public class MqttController { @PostMapping("/on") public String turnOn() { - publisher.publishCommand("mycafe/relay/control", "on"); + mqttService.turnOn(); return "Sent ON command"; } @PostMapping("/off") public String turnOff() { - publisher.publishCommand("mycafe/relay/control", "off"); + mqttService.turnOff(); return "Sent OFF command"; } @PostMapping("/time") public String setTimer(@RequestParam Long cafeId, int time) { - String message = mqttService.getTimerMessage(cafeId, time); - publisher.publishCommand("mycafe/relay/control", message); - return "Timer set"; + String message = mqttService.startTimer(cafeId, time); + return "Timer set " + message; } } diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttPublisher.java b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttPublisher.java index 915e07f..b129923 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttPublisher.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttPublisher.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -@Profile("!test") + @Slf4j @Service public class MqttPublisher { diff --git a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttService.java b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttService.java index cf99571..0a2cf35 100644 --- a/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttService.java +++ b/src/main/java/com/cagong/receiptpowerserver/domain/mqtt/MqttService.java @@ -19,8 +19,17 @@ public class MqttService { private final MileageRepository mileageRepository; private final MemberRepository memberRepository; private final CafeRepository cafeRepository; + private final MqttPublisher publisher; - public String getTimerMessage(Long cafeId, int time){ + public void turnOn(){ + publisher.publishCommand("mycafe/relay/control", "on"); + } + + public void turnOff(){ + publisher.publishCommand("mycafe/relay/control", "off"); + } + + public String startTimer(Long cafeId, int time){ Long memberId = MemberUtil.getCurrentMember(); Member member = memberRepository.findById(memberId) @@ -29,13 +38,9 @@ public String getTimerMessage(Long cafeId, int time){ Cafe cafe = cafeRepository.findById(cafeId) .orElseThrow(() -> new RuntimeException("카페를 찾을 수 없습니다.")); - // Mileage 엔티티가 없으면 0으로 계산 - int remainingMileageTime = mileageRepository.findByMemberAndCafe(member, cafe) - .map(Mileage::getPoint) - .orElse(0); + String message = "time:" + time; - int returnTime = remainingMileageTime + time; - String message = "time:" + returnTime; + publisher.publishCommand("mycafe/relay/control", message); return message; } diff --git a/src/main/java/com/cagong/receiptpowerserver/global/config/MqttConfig.java b/src/main/java/com/cagong/receiptpowerserver/global/config/MqttConfig.java index 9f88011..b6a4b2e 100644 --- a/src/main/java/com/cagong/receiptpowerserver/global/config/MqttConfig.java +++ b/src/main/java/com/cagong/receiptpowerserver/global/config/MqttConfig.java @@ -11,7 +11,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -@Profile("!test") @Configuration @Slf4j public class MqttConfig { diff --git a/src/test/java/com/cagong/receiptpowerserver/mileage/MileageTest.java b/src/test/java/com/cagong/receiptpowerserver/mileage/MileageTest.java index 146b9b2..1d7a114 100644 --- a/src/test/java/com/cagong/receiptpowerserver/mileage/MileageTest.java +++ b/src/test/java/com/cagong/receiptpowerserver/mileage/MileageTest.java @@ -14,6 +14,8 @@ import com.cagong.receiptpowerserver.domain.mileage.dto.EndMileageUsageResponse; import com.cagong.receiptpowerserver.domain.mileage.dto.SaveMileageRequest; import com.cagong.receiptpowerserver.domain.mileage.dto.SaveMileageResponse; +import com.cagong.receiptpowerserver.domain.mqtt.MqttPublisher; +import com.cagong.receiptpowerserver.domain.mqtt.MqttService; import com.cagong.receiptpowerserver.global.security.CustomUserDetails; import com.fasterxml.jackson.databind.ObjectMapper; import io.restassured.RestAssured; @@ -27,6 +29,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -49,6 +52,12 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) public class MileageTest { + @MockBean + private MqttPublisher mqttPublisher; + + @MockBean + private MqttService mqttService; + @Autowired private PasswordEncoder passwordEncoder; @Autowired @@ -175,14 +184,14 @@ private Cafe createTestCafe(String name, String address, String phoneNumber) { .build(); Mileage savedMileage = mileageRepository.save(mileage); */ - SaveMileageRequest request = new SaveMileageRequest(savedCafe.getId(),100); + SaveMileageRequest request = new SaveMileageRequest(savedCafe.getId(),3000); mileageService.addMileage(request); // Then - 검증 //Optional found = mileageRepository.findById(savedMileage.getId()); CafeMileageResponse response = mileageService.getCafeMileage(savedCafe.getId()); - Assertions.assertThat(response.getPoints()).isEqualTo(100); + Assertions.assertThat(response.getPoints()).isEqualTo(120); /* Assertions.assertThat(found).isPresent(); Assertions.assertThat(found.get().getPoint()).isEqualTo(1000); @@ -337,7 +346,7 @@ private Cafe createTestCafe(String name, String address, String phoneNumber) { .build(); cafeRepository.save(cafe); - SaveMileageRequest request = new SaveMileageRequest(cafe.getId(), 100); + SaveMileageRequest request = new SaveMileageRequest(cafe.getId(), 3000); given(). header(AUTHORIZATION, authorizationValue). @@ -360,7 +369,7 @@ private Cafe createTestCafe(String name, String address, String phoneNumber) { .as(CafeMileageResponse.class); assertThat(response.getCafeId()).isEqualTo(cafe.getId()); - assertThat(response.getPoints()).isEqualTo(100); + assertThat(response.getPoints()).isEqualTo(120); } @Test