From 2ba432c43dad7439b19fbfca12757d5530897db3 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期三, 22 四月 2026 15:55:10 +0800
Subject: [PATCH] 根据起始站点和终点站点获取第一条线路目的地列表

---
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineMapper.xml       |   41 ++++++++
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/SiteServiceImpl.java |  126 +++++++++++++++++++++++-
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ISiteService.java         |    9 +
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/LineController.java   |   31 ++++++
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineServiceImpl.java |   41 ++++++++
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/SiteController.java   |   20 ++++
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ILineService.java         |   17 +++
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineMapper.java              |   14 ++
 8 files changed, 290 insertions(+), 9 deletions(-)

diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/LineController.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/LineController.java
index 95abc9e..aaea20b 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/LineController.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/LineController.java
@@ -59,6 +59,37 @@
         }
     }
 
+    @ResponseBody
+    @RequestMapping(value = "/base/line/queryFirstLineDestinations", method = RequestMethod.POST)
+    @ApiOperation(value = "根据起始站点和终点站点获取第一条线路目的地列表", tags = {"用户端-跨城"}, notes = "可能为空")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "起始站点id", name = "startId", required = true, dataType = "int"),
+            @ApiImplicitParam(value = "终点站点id", name = "endId", required = true, dataType = "int")
+    })
+    public ResultUtil<List<Map<String, Object>>> queryFirstLineDestinations(Integer startId, Integer endId){
+        try {
+            return ResultUtil.success(lineService.queryFirstLineDestinations(startId, endId));
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
+    @ResponseBody
+    @RequestMapping(value = "/base/line/queryFutureLinesByDriver", method = RequestMethod.POST)
+    @ApiOperation(value = "根据司机id获取当前时间之后发车的城际线路", tags = {"用户端-跨城"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "司机id", name = "driverId", required = true, dataType = "int")
+    })
+    public ResultUtil<List<Map<String, Object>>> queryFutureLinesByDriver(Integer driverId){
+        try {
+            return ResultUtil.success(lineService.queryFutureLinesByDriver(driverId));
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
 
     @ResponseBody
     @RequestMapping(value = "/base/line/confirm", method = RequestMethod.POST)
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/SiteController.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/SiteController.java
index afe79ca..1f811ab 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/SiteController.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/SiteController.java
@@ -1,6 +1,7 @@
 package com.stylefeng.guns.modular.crossCity.controller;
 
 
+import com.stylefeng.guns.modular.crossCity.model.Site;
 import com.stylefeng.guns.modular.crossCity.server.ISiteService;
 import com.stylefeng.guns.modular.crossCity.warpper.LocationWarpper;
 import com.stylefeng.guns.modular.crossCity.warpper.SiteWarpper;
@@ -91,6 +92,25 @@
         }
     }
 
+    /**
+     * 根据经纬度查询所在站点(可能为空,命中多个时返回第一个)
+     */
+    @ResponseBody
+    @RequestMapping(value = "/base/site/querySiteByLonLat", method = RequestMethod.POST)
+    @ApiOperation(value = "根据经纬度获取所在站点", tags = {"用户端-跨城"}, notes = "可能为空;命中多个时返回第一个")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "经度", name = "lon", required = true, dataType = "double"),
+            @ApiImplicitParam(value = "纬度", name = "lat", required = true, dataType = "double")
+    })
+    public ResultUtil<Site> querySiteByLonLat(Double lon, Double lat){
+        try {
+            return ResultUtil.success(siteService.querySiteByLonLat(lon, lat));
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
 
 
 }
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineMapper.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineMapper.java
index a636586..f801749 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineMapper.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineMapper.java
@@ -25,4 +25,18 @@
      * @return
      */
     List<Map<String, Object>> scanCodeQueryLines(@Param("driverId") Integer driverId);
+
+    /**
+     * 根据司机id查询当前时间之后发车的城际线路
+     * @param driverId
+     * @return
+     */
+    List<Map<String, Object>> queryFutureLinesByDriver(@Param("driverId") Integer driverId);
+
+    /**
+     * 根据线路id查询目的地列表
+     * @param lineId
+     * @return
+     */
+    List<Map<String, Object>> queryLineDestinations(@Param("lineId") Integer lineId);
 }
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineMapper.xml b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineMapper.xml
index a42144e..28e29a0 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineMapper.xml
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineMapper.xml
@@ -22,6 +22,7 @@
         left join t_line_site b on (a.id = b.lineId)
         left join t_site c on (b.siteId = c.id)
         where a.state = 1 and b.siteId = #{siteId} and b.type = #{type}
+        order by a.id asc
     </select>
 
 
@@ -33,4 +34,42 @@
         left join t_line b on (a.lineId = b.id)
         where b.state = 1 and a.driverId = #{driverId}
     </select>
-</mapper>
\ No newline at end of file
+
+    <select id="queryFutureLinesByDriver" resultType="map">
+        select
+        l.id as id,
+        l.`name` as `name`,
+        min(str_to_date(concat(date_format(lsd.`day`, '%Y-%m-%d'), ' ', ls.startTime), '%Y-%m-%d %H:%i')) as departTime
+        from t_line_shift_driver lsd
+        left join t_line_shift ls on ls.id = lsd.lineShiftId
+        left join t_line l on l.id = ls.lineId
+        where lsd.driverId = #{driverId}
+          and lsd.`day` is not null
+          and ls.state = 1
+          and l.state = 1
+          and str_to_date(concat(date_format(lsd.`day`, '%Y-%m-%d'), ' ', ls.startTime), '%Y-%m-%d %H:%i') >= now()
+        group by l.id, l.`name`
+        order by departTime asc, l.id asc
+    </select>
+
+    <select id="queryLineDestinations" resultType="map">
+        select
+        id,
+        lineId,
+        `name`,
+        fenceType,
+        coordinate,
+        defaultPointLon,
+        defaultPointLat,
+        price5,
+        price7,
+        `state`,
+        isMain,
+        addTime,
+        insertTime
+        from t_line_destination
+        where lineId = #{lineId}
+          and state != 3
+        order by isMain desc, id asc
+    </select>
+</mapper>
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ILineService.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ILineService.java
index c171276..c1b60f3 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ILineService.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ILineService.java
@@ -27,4 +27,21 @@
      * @throws Exception
      */
     List<Map<String, Object>> scanCodeQueryLines(Integer driverId) throws Exception;
+
+    /**
+     * 根据司机id查询当前时间之后发车的城际线路
+     * @param driverId
+     * @return
+     * @throws Exception
+     */
+    List<Map<String, Object>> queryFutureLinesByDriver(Integer driverId) throws Exception;
+
+    /**
+     * 根据起始站点和终点站点查询第一条线路的目的地列表
+     * @param startId
+     * @param endId
+     * @return
+     * @throws Exception
+     */
+    List<Map<String, Object>> queryFirstLineDestinations(Integer startId, Integer endId) throws Exception;
 }
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ISiteService.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ISiteService.java
index c701187..3edbc5f 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ISiteService.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/ISiteService.java
@@ -36,4 +36,13 @@
      * @throws Exception
      */
     boolean areaMonitoring(Integer siteId, Integer code, String lonLat) throws Exception;
+
+    /**
+     * 根据经纬度查询所在站点(命中多个时返回第一个)
+     * @param lon 经度
+     * @param lat 纬度
+     * @return 站点(可能为空)
+     * @throws Exception
+     */
+    Site querySiteByLonLat(Double lon, Double lat) throws Exception;
 }
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineServiceImpl.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineServiceImpl.java
index a557929..c366b56 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineServiceImpl.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineServiceImpl.java
@@ -8,6 +8,7 @@
 
 import javax.annotation.Resource;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -70,4 +71,44 @@
     public List<Map<String, Object>> scanCodeQueryLines(Integer driverId) throws Exception {
         return lineMapper.scanCodeQueryLines(driverId);
     }
+
+    /**
+     * 根据司机id查询当前时间之后发车的城际线路
+     */
+    @Override
+    public List<Map<String, Object>> queryFutureLinesByDriver(Integer driverId) throws Exception {
+        if (driverId == null) {
+            return new ArrayList<>();
+        }
+        return lineMapper.queryFutureLinesByDriver(driverId);
+    }
+
+    /**
+     * 根据起始站点和终点站点查询第一条线路的目的地列表
+     */
+    @Override
+    public List<Map<String, Object>> queryFirstLineDestinations(Integer startId, Integer endId) throws Exception {
+        List<Map<String, Object>> lines = queryLines(startId, endId, null);
+        if (lines == null || lines.size() <= 0) {
+            return new ArrayList<>();
+        }
+        Map<String, Object> firstLine = lines.get(0);
+        if (firstLine == null || firstLine.get("id") == null) {
+            return new ArrayList<>();
+        }
+        Integer lineId = Integer.valueOf(firstLine.get("id").toString());
+        List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
+        if (destinations == null || destinations.size() <= 0) {
+            return new ArrayList<>();
+        }
+        for (Map<String, Object> destination : destinations) {
+            Map<String, Object> fenceInfo = new HashMap<>();
+            fenceInfo.put("fenceType", destination.get("fenceType"));
+            fenceInfo.put("coordinate", destination.get("coordinate"));
+            fenceInfo.put("defaultPointLon", destination.get("defaultPointLon"));
+            fenceInfo.put("defaultPointLat", destination.get("defaultPointLat"));
+            destination.put("fenceInfo", fenceInfo);
+        }
+        return destinations;
+    }
 }
diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/SiteServiceImpl.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/SiteServiceImpl.java
index 2e896e8..1742b93 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/SiteServiceImpl.java
+++ b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/SiteServiceImpl.java
@@ -2,19 +2,21 @@
 
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.stylefeng.guns.core.util.ToolUtil;
 import com.stylefeng.guns.modular.crossCity.dao.LocationMapper;
 import com.stylefeng.guns.modular.crossCity.dao.SiteMapper;
 import com.stylefeng.guns.modular.crossCity.model.Site;
 import com.stylefeng.guns.modular.crossCity.server.ISiteService;
 import com.stylefeng.guns.modular.crossCity.warpper.SiteWarpper;
-import com.stylefeng.guns.modular.system.util.GDMapElectricFenceUtil;
 import com.stylefeng.guns.modular.system.util.model.GeoFencingPolygon;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import java.util.*;
@@ -31,7 +33,12 @@
     private LocationMapper locationMapper;
 
     @Autowired
-    private MongoTemplate mongoTemplate;
+    private ObjectProvider<MongoTemplate> mongoTemplateProvider;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    private static final String AMAP_KEY = "6dd64582ed31b84134ac38b2355eb82b";
 
 
     /**
@@ -112,12 +119,7 @@
                 }
             }
             if(Integer.valueOf(map.get("type").toString()) == 2){//电子围栏
-                String[] split = lonLat.split(",");
-                GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(split[0]), Double.valueOf(split[1]));
-                Query query = Query.query(Criteria.where("geoJsonPolygon").intersects(point));
-                List<GeoFencingPolygon> geoFencingPolygons = mongoTemplate.find(query, GeoFencingPolygon.class);
-                List<Integer> s_sites = geoFencingPolygons.stream().map(GeoFencingPolygon::getSiteId).collect(Collectors.toList());
-                if(s_sites.contains(siteId)){
+                if(matchAreaType2(siteId, lonLat)){
                     return true;
                 }
             }
@@ -135,4 +137,112 @@
     public List<Map<String, Object>> queryLocation(Integer siteId) throws Exception {
         return locationMapper.queryLocation(siteId);
     }
+
+    /**
+     * 根据经纬度查询所在站点(命中多个时返回第一个)
+     */
+    @Override
+    public Site querySiteByLonLat(Double lon, Double lat) throws Exception {
+        if (lon == null || lat == null) {
+            return null;
+        }
+        String adCode = getAdCodeByLonLat(lon, lat);
+        String lonLat = lon + "," + lat;
+        List<Site> siteList = this.selectList(new EntityWrapper<Site>().eq("state", 1).orderBy("id", true));
+        if (siteList == null || siteList.size() <= 0) {
+            return null;
+        }
+        for (Site site : siteList) {
+            if (site == null || site.getId() == null) {
+                continue;
+            }
+            List<Map<String, Object>> locations = queryLocation(site.getId());
+            if (locations == null || locations.size() <= 0) {
+                continue;
+            }
+            if (matchAreaType1(locations, adCode) || matchAreaType2(site.getId(), lonLat)) {
+                return site;
+            }
+        }
+        return null;
+    }
+
+    private boolean matchAreaType1(List<Map<String, Object>> locations, String adCode) {
+        if (ToolUtil.isEmpty(adCode)) {
+            return false;
+        }
+        if (adCode.length() < 4) {
+            return false;
+        }
+        String province = adCode.substring(0, 2) + "0000";
+        String city = adCode.substring(0, 4) + "00";
+        for (Map<String, Object> map : locations) {
+            if (map == null || map.get("type") == null) {
+                continue;
+            }
+            if (Integer.valueOf(map.get("type").toString()) != 1) {
+                continue;
+            }
+            if (map.get("districtCode") != null && adCode.equals(map.get("districtCode").toString())) {
+                return true;
+            }
+            if (map.get("cityCode") != null && city.equals(map.get("cityCode").toString())) {
+                return true;
+            }
+            if (map.get("provinceCode") != null && province.equals(map.get("provinceCode").toString())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean matchAreaType2(Integer siteId, String lonLat) {
+        MongoTemplate mongoTemplate;
+        try {
+            mongoTemplate = mongoTemplateProvider.getIfAvailable();
+        } catch (Exception ex) {
+            return false;
+        }
+        if (mongoTemplate == null || ToolUtil.isEmpty(lonLat)) {
+            return false;
+        }
+        String[] split = lonLat.split(",");
+        if (split.length != 2) {
+            return false;
+        }
+        GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(split[0]), Double.valueOf(split[1]));
+        Query query = Query.query(Criteria.where("geoJsonPolygon").intersects(point));
+        List<GeoFencingPolygon> geoFencingPolygons = mongoTemplate.find(query, GeoFencingPolygon.class);
+        if (geoFencingPolygons == null || geoFencingPolygons.size() <= 0) {
+            return false;
+        }
+        List<Integer> siteIds = geoFencingPolygons.stream().map(GeoFencingPolygon::getSiteId).collect(Collectors.toList());
+        return siteIds.contains(siteId);
+    }
+
+    private String getAdCodeByLonLat(Double lon, Double lat) {
+        try {
+            String location = lon + "," + lat;
+            String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + AMAP_KEY + "&location=" + location;
+            String body = restTemplate.getForObject(url, String.class);
+            if (ToolUtil.isEmpty(body)) {
+                return null;
+            }
+            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(body);
+            if (!"1".equals(jsonObject.getString("status"))) {
+                return null;
+            }
+            com.alibaba.fastjson.JSONObject regeocode = jsonObject.getJSONObject("regeocode");
+            if (regeocode == null) {
+                return null;
+            }
+            com.alibaba.fastjson.JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
+            if (addressComponent == null) {
+                return null;
+            }
+            return addressComponent.getString("adcode");
+        } catch (Exception ex) {
+            return null;
+        }
+    }
 }

--
Gitblit v1.7.1