#
vincentlu
2026-04-07 30c540d35e476f9dc1c7149a4e52088c7f375f60
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package com.zy.acs.manager.manager.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
import com.zy.acs.manager.core.service.MapService;
import com.zy.acs.manager.manager.entity.Code;
import com.zy.acs.manager.manager.entity.CodeGap;
import com.zy.acs.manager.manager.entity.Route;
import com.zy.acs.manager.manager.mapper.CodeGapMapper;
import com.zy.acs.manager.manager.service.CodeGapService;
import com.zy.acs.manager.manager.service.RouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
@Slf4j
@Service("codeGapService")
public class CodeGapServiceImpl extends ServiceImpl<CodeGapMapper, CodeGap> implements CodeGapService {
 
    public static final Map<String, CodeGap> GAP_DISTANCE_CACHE = new HashMap<>();
 
    @Autowired
    private MapService mapService;
    @Autowired
    private RouteService routeService;
 
    @PostConstruct
    public void init() {
        for (CodeGap codeGap : this.list()) {
            String gapKey = generateGapKey(codeGap.getCode0(), codeGap.getCode1());
            if (!Cools.isEmpty(gapKey)) {
                GAP_DISTANCE_CACHE.put(gapKey, codeGap);
            }
        }
        log.info("The gap cache was initialized...");
    }
 
 
    @Override
    public CodeGap createCodeGapByCode(Code code0, Code code1, Long userId) {
        if (code0.getData().equals(code1.getData())) {
            return null;
        }
        CodeGap codeGap = findByCodeOfBoth(code0.getId(), code1.getId());
        if (null == codeGap) {
            Date now = new Date();
            codeGap = new CodeGap();
 
            codeGap.setCode0(code0.getId());
            codeGap.setCode1(code1.getId());
            double distance = mapService.calculateDistance(code0.getX(), code0.getY(), code1.getX(), code1.getY());
            codeGap.setDistance(distance);
 
            codeGap.setStatus(1);
            codeGap.setCreateBy(userId);
            codeGap.setCreateTime(now);
            codeGap.setUpdateBy(userId);
            codeGap.setUpdateTime(now);
            if (!this.save(codeGap)) {
                throw new CoolException(code0.getData() + "-" + code1.getData() + " save fail![Route]");
            }
        }
        return codeGap;
    }
 
    @Override
    public CodeGap findByCodeOfBoth(Long code0, Long code1) {
        CodeGap codeGap = null;
        String gapKey = generateGapKey(code0, code1);
        if (!Cools.isEmpty(gapKey)) {
            codeGap = GAP_DISTANCE_CACHE.get(gapKey);
        }
 
        if (null == codeGap) {
            codeGap = this.getOne(new LambdaQueryWrapper<CodeGap>()
                    .eq(CodeGap::getCode0, code0).eq(CodeGap::getCode1, code1).last("limit 1"));
            if (codeGap == null) {
                codeGap = this.getOne(new LambdaQueryWrapper<CodeGap>()
                        .eq(CodeGap::getCode1, code0).eq(CodeGap::getCode0, code1).last("limit 1"));
            }
        }
 
        if (null == codeGap) {
//            throw new CoolException("failed to find code of both " + code0 + " and " + code1);
        }
 
        return codeGap;
    }
 
    @Override
    public Double findDistanceByCode(Long code0, Long code1) {
        return 0.0;
    }
 
    @Override
    public void removeCodeGapIfUnused(Long code0, Long code1) {
        if (code0 == null || code1 == null) {
            return;
        }
        long count = routeService.count(new LambdaQueryWrapper<Route>()
                .eq(Route::getStartCode, code0)
                .eq(Route::getEndCode, code1))
                + routeService.count(new LambdaQueryWrapper<Route>()
                .eq(Route::getStartCode, code1)
                .eq(Route::getEndCode, code0));
        if (count > 0) {
            return;
        }
        CodeGap codeGap = findByCodeOfBoth(code0, code1);
        if (codeGap != null && !this.removeById(codeGap.getId())) {
            throw new CoolException("Delete Fail");
        }
    }
 
    @Override
    public boolean save(CodeGap entity) {
        boolean result = super.save(entity);
        if (result) {
            String gapKey = generateGapKey(entity.getCode0(), entity.getCode1());
            if (!Cools.isEmpty(gapKey)) {
                GAP_DISTANCE_CACHE.put(gapKey, entity);
            }
        }
        return result;
    }
 
    @Override
    public boolean removeById(Serializable id) {
        CodeGap codeGap = this.getById(id);
        boolean result = super.removeById(id);
        if (result && codeGap != null) {
            String gapKey = generateGapKey(codeGap.getCode0(), codeGap.getCode1());
            if (!Cools.isEmpty(gapKey)) {
                GAP_DISTANCE_CACHE.remove(gapKey);
            }
        }
        return result;
    }
 
    private static String generateGapKey(Long code0, Long code1) {
        if (Cools.isEmpty(code0, code1)) {
            return null;
        }
        if (code1 < code0) {
            return code1 + "-" + code0;
        }
        return code0 + "-" + code1;
    }
 
}