package com.tourguide.modules.user.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.tourguide.common.exception.BusinessException; import com.tourguide.modules.operation.entity.OperationScenicSpot; import com.tourguide.modules.operation.entity.ScenicMeetingPoint; import com.tourguide.modules.operation.mapper.OperationScenicSpotMapper; import com.tourguide.modules.operation.mapper.ScenicMeetingPointMapper; import com.tourguide.modules.user.dto.GuideRealtimeStatusRequest; import com.tourguide.modules.user.dto.GuideRealtimeStatusResponse; import com.tourguide.modules.user.entity.GuideRealtimeStatus; import com.tourguide.modules.user.entity.GuideScenicConfig; import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper; import com.tourguide.modules.user.mapper.GuideScenicConfigMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; /** 导游实时定位及接单状态服务。 */ @Service public class GuideRealtimeStatusService { private final GuideUserService guideUserService; private final GuideRealtimeStatusMapper statusMapper; private final GuideScenicConfigMapper scenicConfigMapper; private final OperationScenicSpotMapper scenicSpotMapper; private final ScenicMeetingPointMapper meetingPointMapper; public GuideRealtimeStatusService(GuideUserService guideUserService, GuideRealtimeStatusMapper statusMapper, GuideScenicConfigMapper scenicConfigMapper, OperationScenicSpotMapper scenicSpotMapper, ScenicMeetingPointMapper meetingPointMapper) { this.guideUserService = guideUserService; this.statusMapper = statusMapper; this.scenicConfigMapper = scenicConfigMapper; this.scenicSpotMapper = scenicSpotMapper; this.meetingPointMapper = meetingPointMapper; } @Transactional public GuideRealtimeStatusResponse update(Long guideId, GuideRealtimeStatusRequest request) { guideUserService.findEnabledById(guideId); OperationScenicSpot scenicSpot = scenicSpotMapper.selectOne( new LambdaQueryWrapper() .eq(OperationScenicSpot::getId, request.getScenicSpotId()) .eq(OperationScenicSpot::getStatus, 1)); if (scenicSpot == null) { throw new BusinessException(404, "景区不存在或未启用"); } validateGuideScenic(guideId, scenicSpot.getScenicName()); validateMeetingPoint(request.getMeetingPointId(), scenicSpot.getId()); GuideRealtimeStatus status = statusMapper.selectById(guideId); if (status == null) { status = new GuideRealtimeStatus(); status.setGuideId(guideId); } status.setScenicSpotId(scenicSpot.getId()); status.setMeetingPointId(request.getMeetingPointId()); status.setLongitude(request.getLongitude()); status.setLatitude(request.getLatitude()); status.setOnlineStatus(request.getOnlineStatus()); status.setAvailableStatus(request.getOnlineStatus() == 1 ? request.getAvailableStatus() : 0); status.setLastLocationAt(LocalDateTime.now()); if (statusMapper.selectById(guideId) == null) { statusMapper.insert(status); } else { statusMapper.updateById(status); } return new GuideRealtimeStatusResponse(statusMapper.selectById(guideId)); } public GuideRealtimeStatusResponse get(Long guideId) { guideUserService.findEnabledById(guideId); GuideRealtimeStatus status = statusMapper.selectById(guideId); return status == null ? null : new GuideRealtimeStatusResponse(status); } private void validateGuideScenic(Long guideId, String scenicName) { long configured = scenicConfigMapper.selectCount( new LambdaQueryWrapper() .eq(GuideScenicConfig::getGuideId, guideId) .eq(GuideScenicConfig::getScenicName, scenicName)); if (configured == 0) { throw new BusinessException(403, "导游未配置当前景区服务权限"); } } private void validateMeetingPoint(Long meetingPointId, Long scenicSpotId) { if (meetingPointId == null) { return; } long count = meetingPointMapper.selectCount( new LambdaQueryWrapper() .eq(ScenicMeetingPoint::getId, meetingPointId) .eq(ScenicMeetingPoint::getScenicSpotId, scenicSpotId) .eq(ScenicMeetingPoint::getStatus, 1)); if (count == 0) { throw new BusinessException(400, "汇合点不属于当前景区或已停用"); } } }