JourneyService.java 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package com.izouma.walkchina.service;
  2. import com.izouma.walkchina.constant.AppConstants;
  3. import com.izouma.walkchina.constant.Strings;
  4. import com.izouma.walkchina.domain.*;
  5. import com.izouma.walkchina.dto.Location;
  6. import com.izouma.walkchina.dto.webservice.DirectionResponse;
  7. import com.izouma.walkchina.dto.webservice.MapRoute;
  8. import com.izouma.walkchina.exception.ServiceException;
  9. import com.izouma.walkchina.repo.*;
  10. import lombok.extern.slf4j.Slf4j;
  11. import org.joda.time.Days;
  12. import org.joda.time.LocalDate;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import java.math.BigDecimal;
  16. import java.util.*;
  17. @Service
  18. @Slf4j
  19. public class JourneyService {
  20. @Autowired
  21. private UserJourneyRepository userJourneyRepository;
  22. @Autowired
  23. private JourneyStageRepository journeyStageRepository;
  24. @Autowired
  25. private WalkDataRepository walkDataRepository;
  26. @Autowired
  27. private TeamMemberRepository teamMemberRepository;
  28. @Autowired
  29. private MessageRepository messageRepository;
  30. @Autowired
  31. private CityRepository cityRepository;
  32. @Autowired
  33. private MapService mapService;
  34. @Autowired
  35. private StageAwardRepository stageAwardRepository;
  36. public boolean hasJourney(Long userId) {
  37. return userJourneyRepository.findByUserId(userId) != null;
  38. }
  39. public void newJourney(Long userId, Long originId, Long destinationId) {
  40. City origin = cityRepository.findById(originId).orElseThrow(new ServiceException("起始地不存在"));
  41. City destination = cityRepository.findById(destinationId).orElseThrow(new ServiceException("目的地不存在"));
  42. DirectionResponse directionResponse = mapService.direction(new Location(origin.getLatitude(), origin.getLongitude()),
  43. new Location(destination.getLatitude(), destination.getLongitude()));
  44. if (directionResponse.getStatus() != 0) {
  45. throw new ServiceException(directionResponse.getMessage());
  46. }
  47. UserJourney userJourney = UserJourney.builder()
  48. .userId(userId)
  49. .originId(originId)
  50. .destinationId(destinationId)
  51. .distance(directionResponse.getResult().getRoutes().get(0).getDistance())
  52. .polyline(directionResponse.getResult().getRoutes().get(0).getPolyline())
  53. .build();
  54. userJourney = userJourneyRepository.save(userJourney);
  55. int distance = directionResponse.getResult().getRoutes().get(0).getDistance();
  56. JourneyStage journeyStage = JourneyStage.builder()
  57. .userId(userId)
  58. .journeyId(userJourney.getId())
  59. .originId(originId)
  60. .destinationId(destinationId)
  61. .polyline(directionResponse.getResult().getRoutes().get(0).getPolyline())
  62. .routeSteps(directionResponse.getResult().getRoutes().get(0).getSteps())
  63. .distance(directionResponse.getResult().getRoutes().get(0).getDistance())
  64. .progress(.0)
  65. .steps(Math.round(distance / AppConstants.STEP_TO_DISTANCE_RATE))
  66. .award(BigDecimal.valueOf(Math.round(distance * AppConstants.DISTANCE_TO_COIN_RATE)))
  67. .build();
  68. journeyStage = journeyStageRepository.save(journeyStage);
  69. createStageAward(userId, journeyStage.getId(), userJourney.getId(), directionResponse.getResult().getRoutes().get(0));
  70. }
  71. public void newDestination(Long userId, Long id) {
  72. City destination = cityRepository.findById(id).orElseThrow(new ServiceException("目的地不存在"));
  73. UserJourney userJourney = userJourneyRepository.findByUserId(userId);
  74. JourneyStage journeyStage = journeyStageRepository.findByUserIdAndJourneyIdOrderByIdDesc(userId, userJourney.getId());
  75. DirectionResponse directionResponse = mapService.direction(new Location(journeyStage.getDestination().getLatitude(), journeyStage.getDestination().getLongitude()),
  76. new Location(destination.getLatitude(), destination.getLongitude()));
  77. if (directionResponse.getStatus() != 0) {
  78. throw new ServiceException(directionResponse.getMessage());
  79. }
  80. MapRoute route = directionResponse.getResult().getRoutes().get(0);
  81. List<Double> newPolyline = new ArrayList<>(route.getPolyline());
  82. JourneyStage newStage = JourneyStage.builder()
  83. .userId(userId)
  84. .journeyId(userJourney.getId())
  85. .originId(journeyStage.getDestination().getId())
  86. .destinationId(destination.getId())
  87. .distance(route.getDistance())
  88. .progress(.0)
  89. .polyline(route.getPolyline())
  90. .routeSteps(route.getSteps())
  91. .build();
  92. newStage = journeyStageRepository.save(newStage);
  93. List<Double> polyline = mapService.extractPolyline(userJourney.getPolyline());
  94. newPolyline.set(0, newPolyline.get(0) * 1000000 - polyline.get(polyline.size() - 2) * 1000000);
  95. newPolyline.set(1, newPolyline.get(1) * 1000000 - polyline.get(polyline.size() - 1) * 1000000);
  96. userJourney.getPolyline().addAll(newPolyline);
  97. userJourneyRepository.save(userJourney);
  98. createStageAward(userId, newStage.getId(), userJourney.getId(), route);
  99. }
  100. private void createStageAward(Long userId, Long stageId, Long journeyId, MapRoute route) {
  101. List<Double> extracted = mapService.extractPolyline(route.getPolyline());
  102. List<Double> points = Arrays.asList(.3, .6);
  103. for (Double p : points) {
  104. int end = mapService.endPoint(route.getSteps(), route.getDistance() * p);
  105. StageAward stageAward = StageAward.builder()
  106. .userId(userId)
  107. .stageId(stageId)
  108. .latitude(extracted.get(end - 1))
  109. .longitude(extracted.get(end))
  110. .journeyId(journeyId)
  111. .coin(new BigDecimal(10))
  112. .needProgress(p)
  113. .needStep((long) (p * route.getDistance() / AppConstants.STEP_TO_DISTANCE_RATE))
  114. .received(false)
  115. .build();
  116. stageAwardRepository.save(stageAward);
  117. }
  118. }
  119. public void updateUserJourney(Long userId) {
  120. UserJourney userJourney = userJourneyRepository.findByUserId(userId);
  121. if (userJourney == null) {
  122. throw new ServiceException("无数据");
  123. }
  124. List<JourneyStage> stageList = journeyStageRepository.findAllByJourneyIdOrderById(userJourney.getId());
  125. if (stageList.size() == 0) {
  126. throw new ServiceException("无数据");
  127. }
  128. JourneyStage latestStage = stageList.get(stageList.size() - 1);
  129. Long steps = 0L;
  130. WalkData todayWalkData = walkDataRepository.findByUserIdAndDate(userId, new Date());
  131. log.info("createAt type {}", latestStage.getCreatedAt().getClass().getName());
  132. steps += walkDataRepository.sumTeamWalkSteps(userId, latestStage.getCreatedAt(),
  133. Optional.ofNullable(latestStage.getFinishAt()).orElse(new Date()))
  134. .orElse(0L);
  135. steps += walkDataRepository.sumUserWalkSteps(userId, latestStage.getCreatedAt(),
  136. Optional.ofNullable(latestStage.getFinishAt()).orElse(new Date()))
  137. .orElse(0L);
  138. latestStage.setSteps((long) (latestStage.getDistance() / AppConstants.STEP_TO_DISTANCE_RATE));
  139. latestStage.setCurrentSteps(steps);
  140. double progress = steps * AppConstants.STEP_TO_DISTANCE_RATE / latestStage.getDistance();
  141. progress = progress > 1 ? 1 : (progress < 0 ? 0 : progress);
  142. latestStage.setProgress(progress);
  143. journeyStageRepository.save(latestStage);
  144. if (progress == 1) {
  145. Message msg = Message.builder()
  146. .userId(userId)
  147. .content(String.format(Strings.MSG_JOURNEY_PROGRESS,
  148. latestStage.getOrigin().getName(),
  149. latestStage.getDestination().getName(),
  150. (todayWalkData != null ? todayWalkData.getSteps() : 0),
  151. calcDays(latestStage.getCreatedAt(), new Date()),
  152. steps,
  153. Math.round(progress * 100)))
  154. .build();
  155. messageRepository.save(msg);
  156. }
  157. }
  158. private int calcDays(Date start, Date end) {
  159. return Days.daysBetween(LocalDate.fromDateFields(start), LocalDate.fromDateFields(end)).getDays();
  160. }
  161. }