liujie
2026-09-17 825a575deb96cce822468bb9d9ac3e4eea0f91d1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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<OperationScenicSpot>()
                        .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<GuideScenicConfig>()
                        .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<ScenicMeetingPoint>()
                        .eq(ScenicMeetingPoint::getId, meetingPointId)
                        .eq(ScenicMeetingPoint::getScenicSpotId, scenicSpotId)
                        .eq(ScenicMeetingPoint::getStatus, 1));
        if (count == 0) {
            throw new BusinessException(400, "汇合点不属于当前景区或已停用");
        }
    }
}