package com.izouma.walkchina.service; import com.izouma.walkchina.constant.AppConstants; import com.izouma.walkchina.domain.*; import com.izouma.walkchina.dto.Location; import com.izouma.walkchina.constant.Strings; import com.izouma.walkchina.dto.webservice.DirectionResponse; import com.izouma.walkchina.dto.webservice.MapRoute; import com.izouma.walkchina.exception.ServiceException; import com.izouma.walkchina.repo.*; import org.joda.time.Days; import org.joda.time.LocalDate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Optional; @Service public class JourneyService { @Autowired private UserJourneyRepository userJourneyRepository; @Autowired private JourneyStageRepository journeyStageRepository; @Autowired private WalkDataRepository walkDataRepository; @Autowired private TeamMemberRepository teamMemberRepository; @Autowired private MessageRepository messageRepository; @Autowired private CityRepository cityRepository; @Autowired private MapService mapService; public boolean hasJourney(Long userId) { return userJourneyRepository.findByUserId(userId) != null; } public void newJourney(Long userId, Long originId, Long destinationId) { City origin = cityRepository.findById(originId).orElse(null); if (origin == null) { throw new ServiceException("起始地不存在"); } City destination = cityRepository.findById(destinationId).orElse(null); if (destination == null) { throw new ServiceException("目的地不存在"); } DirectionResponse directionResponse = mapService.direction(new Location(origin.getLatitude(), origin.getLongitude()), new Location(destination.getLatitude(), destination.getLongitude())); if (directionResponse.getStatus() != 0) { throw new ServiceException(directionResponse.getMessage()); } UserJourney userJourney = UserJourney.builder() .userId(userId) .originId(originId) .destinationId(destinationId) .distance(directionResponse.getResult().getRoutes().get(0).getDistance()) .polyline(directionResponse.getResult().getRoutes().get(0).getPolyline()) .build(); userJourney = userJourneyRepository.save(userJourney); int distance = directionResponse.getResult().getRoutes().get(0).getDistance(); JourneyStage journeyStage = JourneyStage.builder() .userId(userId) .journeyId(userJourney.getId()) .originId(originId) .destinationId(destinationId) .polyline(directionResponse.getResult().getRoutes().get(0).getPolyline()) .routeSteps(directionResponse.getResult().getRoutes().get(0).getSteps()) .distance(directionResponse.getResult().getRoutes().get(0).getDistance()) .progress(.0) .steps(Math.round(distance / AppConstants.STEP_TO_DISTANCE_RATE)) .award(BigDecimal.valueOf(Math.round(distance * AppConstants.DISTANCE_TO_COIN_RATE))) .build(); journeyStage = journeyStageRepository.save(journeyStage); } public void newDestination(Long userId, Long id) { City destination = cityRepository.findById(id).orElse(null); if (destination == null) { throw new ServiceException("目的地不存在"); } UserJourney userJourney = userJourneyRepository.findByUserId(userId); JourneyStage journeyStage = journeyStageRepository.findByUserIdAndJourneyIdOrderByIdDesc(userId, userJourney.getId()); DirectionResponse directionResponse = mapService.direction(new Location(journeyStage.getDestination().getLatitude(), journeyStage.getDestination().getLongitude()), new Location(destination.getLatitude(), destination.getLongitude())); if (directionResponse.getStatus() != 0) { throw new ServiceException(directionResponse.getMessage()); } MapRoute route = directionResponse.getResult().getRoutes().get(0); JourneyStage newStage = JourneyStage.builder() .userId(userId) .journeyId(userJourney.getId()) .originId(journeyStage.getDestination().getId()) .destinationId(destination.getId()) .distance(route.getDistance()) .progress(.0) .polyline(route.getPolyline()) .routeSteps(route.getSteps()) .build(); newStage = journeyStageRepository.save(newStage); List polyline = mapService.extractPolyline(userJourney.getPolyline()); route.getPolyline().set(0, route.getPolyline().get(0) * 1000000 - polyline.get(polyline.size() - 2) * 1000000); route.getPolyline().set(1, route.getPolyline().get(1) * 1000000 - polyline.get(polyline.size() - 1) * 1000000); userJourney.getPolyline().addAll(route.getPolyline()); userJourneyRepository.save(userJourney); } public void updateUserJourney(Long userId, Date date) { UserJourney userJourney = userJourneyRepository.findByUserId(userId); if (userJourney == null) { throw new ServiceException("无数据"); } List stageList = journeyStageRepository.findAllByJourneyIdOrderById(userJourney.getId()); if (stageList.size() == 0) { throw new ServiceException("无数据"); } JourneyStage latestStage = stageList.get(stageList.size() - 1); Long steps = 0L; WalkData todayWalkData = walkDataRepository.findByUserIdAndDate(userId, date); steps += walkDataRepository.sumTeamWalkSteps(userId, latestStage.getCreatedAt(), Optional.of(latestStage.getFinishAt()).orElse(new Date())) .orElse(0); latestStage.setSteps(steps); double progress = steps * AppConstants.STEP_TO_DISTANCE_RATE / latestStage.getDistance(); progress = progress > 1 ? 1 : progress; latestStage.setProgress(progress); journeyStageRepository.save(latestStage); if (progress == 1) { Message msg = Message.builder() .userId(userId) .content(String.format(Strings.MSG_JOURNEY_PROGRESS, latestStage.getOrigin().getName(), latestStage.getDestination().getName(), (todayWalkData != null ? todayWalkData.getSteps() : 0), calcDays(latestStage.getCreatedAt(), new Date()), steps, Math.round(progress * 100))) .build(); messageRepository.save(msg); } } private int calcDays(Date start, Date end) { return Days.daysBetween(LocalDate.fromDateFields(start), LocalDate.fromDateFields(end)).getDays(); } }