仰望星空〃 8 mēneši atpakaļ
vecāks
revīzija
6c0c95eaa4

+ 9 - 0
bus-biz/src/main/java/bus/mapper/BCourseInfoMapper.java

@@ -1,10 +1,14 @@
 package bus.mapper;
 
+import bus.model.dto.BStationInfoDto;
 import bus.model.dto.page.BCourseInfoPageDto;
 import bus.model.vo.BCourseInfoVo;
 import bus.model.po.*;
 import org.apache.ibatis.annotations.Mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -17,4 +21,9 @@ import java.util.List;
 public interface BCourseInfoMapper extends BaseMapper<BCourseInfoPo> {
 
     List<BCourseInfoVo> list(BCourseInfoPageDto dto);
+
+    List<BStationInfoDto> findNearbyStations(@Param("longitude") BigDecimal longitude,
+                                             @Param("latitude") BigDecimal latitude,
+                                             @Param("distance") Integer distance);
+    List<BCourseInfoVo> findRoutesByStations(@Param("stationIds") List<Long> stationIds);
 }

+ 4 - 0
bus-biz/src/main/java/bus/service/BCourseInfoService.java

@@ -1,11 +1,13 @@
 package bus.service;
 
+import bus.model.dto.BBusTrackInfoDto;
 import bus.model.dto.BCourseInfoDto;
 import bus.model.dto.page.BCourseInfoPageDto;
 import bus.model.vo.BCourseInfoVo;
 import bus.model.po.BCourseInfoPo;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -51,4 +53,6 @@ public interface BCourseInfoService extends IService<BCourseInfoPo> {
      * @return
      */
     void delete(String id);
+
+    List<BBusTrackInfoDto> getNearbyRoutes(BigDecimal latitude, BigDecimal longitude, Integer radius);
 }

+ 235 - 29
bus-biz/src/main/java/bus/service/impl/BCourseInfoServiceImpl.java

@@ -1,10 +1,7 @@
 package bus.service.impl;
 
 import bus.model.SnowflakeUtil;
-import bus.model.dto.BCourseBusDto;
-import bus.model.dto.BCourseInfoDto;
-import bus.model.dto.BCourseStationDto;
-import bus.model.dto.BCourseTimeDto;
+import bus.model.dto.*;
 import bus.model.dto.page.BCourseInfoPageDto;
 import bus.model.po.*;
 import bus.model.vo.BCourseInfoVo;
@@ -12,6 +9,9 @@ import bus.mapper.BCourseInfoMapper;
 
 import bus.service.*;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.orcas.common.sso.model.ExtInfo;
@@ -22,8 +22,8 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.Date;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -50,6 +50,7 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
     private BCourseBusService bCourseBusService;
     @Resource
     private BBusInfoService bBusInfoService;
+
 	/**
      * 详情
      * @param id
@@ -59,7 +60,11 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
     public BCourseInfoDto getDetailById(String id){
         BCourseInfoPo po = this.bCourseInfoMapper.selectById(id);
         BCourseInfoDto bCourseInfoDto = BeanUtil.toBean(po, BCourseInfoDto.class);
-
+        String mapPoint = po.getMapPoint();
+        if(StrUtil.isNotBlank(mapPoint)) {
+            List<BCoursePointDto> fileJsons = JSONUtil.toList(mapPoint, BCoursePointDto.class);
+            bCourseInfoDto.setMapPointList(fileJsons);
+        }
         QueryWrapper<BCourseTimePo> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("course_id", id);
         queryWrapper.orderByAsc("sort");
@@ -71,21 +76,65 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
         queryWrapper1.eq("course_id", id);
         queryWrapper1.orderByAsc("sort");
         List<BCourseStationPo> list1 = bCourseStationService.list(queryWrapper1);
-        List<String> stationIds = list1.stream().map(BCourseStationPo::getStationId).collect(Collectors.toList());
-        QueryWrapper<BStationInfoPo> queryWrapper2 = new QueryWrapper<>();
-        queryWrapper2.in("id", stationIds);
-        List<BStationInfoPo> list2 = bStationInfoService.list(queryWrapper2);
-        bCourseInfoDto.setBCourseStationList(BeanUtil.copyToList(list2, BCourseStationDto.class));
+        if(CollectionUtil.isNotEmpty(list1)) {
+            List<String> stationIds = list1.stream().map(BCourseStationPo::getStationId).collect(Collectors.toList());
+            QueryWrapper<BStationInfoPo> queryWrapper2 = new QueryWrapper<>();
+            queryWrapper2.in("id", stationIds);
+            List<BStationInfoPo> list2 = bStationInfoService.list(queryWrapper2);
+            Map<String,BStationInfoPo> collect = list2.stream().collect(Collectors.toMap(BStationInfoPo::getId, b -> b));
+            List<BCourseStationDto> list5 = new ArrayList<>();
+            for (BCourseStationPo bCourseStationPo : list1 ) {
+                String stationId = bCourseStationPo.getStationId();
+                BStationInfoPo bStationInfoPo = collect.get(stationId);
+                if(bStationInfoPo != null) {
+                    BCourseStationDto bCourseStationDto = new BCourseStationDto();
+                    bCourseStationDto.setId(bCourseStationPo.getId());
+                    bCourseStationDto.setStationId(bCourseStationPo.getStationId());
+                    bCourseStationDto.setSort(bCourseStationPo.getSort());
+                    bCourseStationDto.setType(bCourseStationPo.getType());
+                    bCourseStationDto.setRemark(bCourseStationPo.getRemark());
+                    bCourseStationDto.setName(bStationInfoPo.getName());
+                    bCourseStationDto.setStationType(bStationInfoPo.getStationType());
+                    bCourseStationDto.setStationStatus(bStationInfoPo.getStationStatus());
+                    bCourseStationDto.setDetailAddress(bStationInfoPo.getDetailAddress());
+                    bCourseStationDto.setStationCode(bStationInfoPo.getStationCode());
+                    bCourseStationDto.setLatitude(bStationInfoPo.getLatitude());
+                    bCourseStationDto.setLongitude(bStationInfoPo.getLongitude());
+                    list5.add(bCourseStationDto);
+                }
+            }
+            bCourseInfoDto.setBCourseStationList(list5);
+        }
 
         QueryWrapper<BCourseBusPo> queryWrapper3 = new QueryWrapper<>();
         queryWrapper3.eq("course_id", id);
         queryWrapper3.orderByAsc("sort");
         List<BCourseBusPo> list3 = bCourseBusService.list(queryWrapper3);
-        List<String> busIds = list3.stream().map(BCourseBusPo::getBusId).collect(Collectors.toList());
-        QueryWrapper<BBusInfoPo> queryWrapper4 = new QueryWrapper<>();
-        queryWrapper4.in("id", busIds);
-        List<BBusInfoPo> list4 = bBusInfoService.list(queryWrapper4);
-        bCourseInfoDto.setBCourseBusList(BeanUtil.copyToList(list4, BCourseBusDto.class));
+        if(CollectionUtil.isNotEmpty(list3)) {
+            List<String> busIds = list3.stream().map(BCourseBusPo::getBusId).collect(Collectors.toList());
+            QueryWrapper<BBusInfoPo> queryWrapper4 = new QueryWrapper<>();
+            queryWrapper4.in("id", busIds);
+            List<BBusInfoPo> list4 = bBusInfoService.list(queryWrapper4);
+            Map<String,BBusInfoPo> collect = list4.stream().collect(Collectors.toMap(BBusInfoPo::getId, b -> b));
+            List<BCourseBusDto> list2 = new ArrayList<>();
+            for (BCourseBusPo bCourseBusPo : list3 ) {
+                String busId = bCourseBusPo.getBusId();
+                BBusInfoPo bBusInfoPo = collect.get(busId);
+                if(bBusInfoPo != null) {
+                    BCourseBusDto bCourseBusDto = new BCourseBusDto();
+                    bCourseBusDto.setId(bCourseBusPo.getId());
+                    bCourseBusDto.setBusId(bCourseBusPo.getBusId());
+                    bCourseBusDto.setSort(bCourseBusPo.getSort());
+                    bCourseBusDto.setRemark(bCourseBusPo.getRemark());
+                    bCourseBusDto.setBusNo(bBusInfoPo.getBusNo());
+                    bCourseBusDto.setDriverName(bBusInfoPo.getDriverName());
+                    bCourseBusDto.setDriverPhone(bBusInfoPo.getDriverPhone());
+                    list2.add(bCourseBusDto);
+                }
+            }
+
+            bCourseInfoDto.setBCourseBusList(list2);
+        }
         return bCourseInfoDto;
     }
 
@@ -98,6 +147,11 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
     @Transactional(rollbackFor = Exception.class)
 	public void save(BCourseInfoDto dto){
         BCourseInfoPo po = BeanUtil.toBean(dto, BCourseInfoPo.class);
+        List<BCoursePointDto> mapPointList = dto.getMapPointList();
+        if(CollectionUtil.isNotEmpty(mapPointList)) {
+            String mapPoint = JSONUtil.toJsonStr(mapPointList);
+            po.setMapPoint(mapPoint);
+        }
         ExtInfo extInfo = CurrentUserHolder.get();
         po.setId(snowflakeUtil.snowflakeId());
         po.setCreateTime(new Date());
@@ -108,8 +162,11 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
         po.setUpdaterName(extInfo.getUserName());
         //处理时刻
         List<BCourseTimeDto> bCourseTimeList = dto.getBCourseTimeList();
-        List<BCourseTimePo> bCourseTimePoList = BeanUtil.copyToList(bCourseTimeList, BCourseTimePo.class);
-        bCourseTimePoList.forEach(bCourseTimePo -> {
+        po.setFirstBusSpace(bCourseTimeList.get(0).getBusSpace());
+        List<BCourseTimePo> bCourseTimePoList = new ArrayList<>();
+        for (int i = 0; i < bCourseTimeList.size(); i++) {
+            BCourseTimeDto bCourseTimeDto = bCourseTimeList.get(i);
+            BCourseTimePo bCourseTimePo = BeanUtil.toBean(bCourseTimeDto, BCourseTimePo.class);
             bCourseTimePo.setId(snowflakeUtil.snowflakeId());
             bCourseTimePo.setCourseId(po.getId());
             bCourseTimePo.setCreateTime(new Date());
@@ -118,12 +175,31 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
             bCourseTimePo.setUpdaterId(extInfo.getUserId());
             bCourseTimePo.setCreatorName(extInfo.getUserName());
             bCourseTimePo.setUpdaterName(extInfo.getUserName());
-        });
+            if (i == 0) {
+                bCourseTimePo.setType("0");
+            }else {
+                bCourseTimePo.setType("1");
+            }
+            bCourseTimePoList.add(bCourseTimePo);
+        }
         bCourseTimeService.saveBatch(bCourseTimePoList);
         //处理标志点
         List<BCourseStationDto> bCourseStationList = dto.getBCourseStationList();
-        List<BCourseStationPo> bCourseStationPoList = BeanUtil.copyToList(bCourseStationList, BCourseStationPo.class);
-        bCourseStationPoList.forEach(bCourseStationPo -> {
+
+        String stationId = bCourseStationList.get(0).getStationId();
+        BStationInfoPo byId = bStationInfoService.getById(stationId);
+        po.setFirstStationName(byId.getName());
+        po.setFirstStationId(stationId);
+
+        String stationId1 = bCourseStationList.get(bCourseStationList.size()-1).getStationId();
+        BStationInfoPo byId1 = bStationInfoService.getById(stationId1);
+        po.setLastStationName(byId1.getName());
+        po.setLastStationId(stationId1);
+
+        List<BCourseStationPo> bCourseStationPoList =new ArrayList<>();
+        for(int i = 0; i < bCourseStationList.size(); i++) {
+            BCourseStationDto bCourseStationDto = bCourseStationList.get(i);
+            BCourseStationPo bCourseStationPo = BeanUtil.toBean(bCourseStationDto, BCourseStationPo.class);
             bCourseStationPo.setId(snowflakeUtil.snowflakeId());
             bCourseStationPo.setCourseId(po.getId());
             bCourseStationPo.setCreateTime(new Date());
@@ -132,7 +208,15 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
             bCourseStationPo.setUpdaterId(extInfo.getUserId());
             bCourseStationPo.setCreatorName(extInfo.getUserName());
             bCourseStationPo.setUpdaterName(extInfo.getUserName());
-        });
+            if (i == 0) {
+                bCourseStationPo.setType("0");
+            }else if(i == bCourseStationList.size()-1) {
+                bCourseStationPo.setType("2");
+            }else{
+                bCourseStationPo.setType("1");
+            }
+            bCourseStationPoList.add(bCourseStationPo);
+        }
         bCourseStationService.saveBatch(bCourseStationPoList);
         //处理车辆
         List<BCourseBusDto> bCourseBusList = dto.getBCourseBusList();
@@ -147,6 +231,7 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
             bCourseBusPo.setCreatorName(extInfo.getUserName());
             bCourseBusPo.setUpdaterName(extInfo.getUserName());
         });
+        bCourseBusService.saveBatch(bCourseBusPoList);
         this.bCourseInfoMapper.insert(po);
     }
 
@@ -168,6 +253,11 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
     @Override
     public void update(BCourseInfoDto dto){
         BCourseInfoPo po = BeanUtil.toBean(dto, BCourseInfoPo.class);
+        List<BCoursePointDto> mapPointList = dto.getMapPointList();
+        if(CollectionUtil.isNotEmpty(mapPointList)) {
+            String mapPoint = JSONUtil.toJsonStr(mapPointList);
+            po.setMapPoint(mapPoint);
+        }
         ExtInfo extInfo = CurrentUserHolder.get();
         po.setUpdateTime(new Date());
         po.setUpdaterId(extInfo.getUserId());
@@ -175,8 +265,11 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
         //处理时刻
         bCourseTimeService.deleteByCourseId(po.getId());
         List<BCourseTimeDto> bCourseTimeList = dto.getBCourseTimeList();
-        List<BCourseTimePo> bCourseTimePoList = BeanUtil.copyToList(bCourseTimeList, BCourseTimePo.class);
-        bCourseTimePoList.forEach(bCourseTimePo -> {
+        po.setFirstBusSpace(bCourseTimeList.get(0).getBusSpace());
+        List<BCourseTimePo> bCourseTimePoList = new ArrayList<>();
+        for (int i = 0; i < bCourseTimeList.size(); i++) {
+            BCourseTimeDto bCourseTimeDto = bCourseTimeList.get(i);
+            BCourseTimePo bCourseTimePo = BeanUtil.toBean(bCourseTimeDto, BCourseTimePo.class);
             bCourseTimePo.setId(snowflakeUtil.snowflakeId());
             bCourseTimePo.setCourseId(po.getId());
             bCourseTimePo.setCreateTime(new Date());
@@ -185,13 +278,26 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
             bCourseTimePo.setUpdaterId(extInfo.getUserId());
             bCourseTimePo.setCreatorName(extInfo.getUserName());
             bCourseTimePo.setUpdaterName(extInfo.getUserName());
-        });
+            if (i == 0) {
+                bCourseTimePo.setType("0");
+            }else {
+                bCourseTimePo.setType("1");
+            }
+            bCourseTimePoList.add(bCourseTimePo);
+        }
         bCourseTimeService.saveBatch(bCourseTimePoList);
         //处理标志点
         bCourseStationService.deleteByCourseId(po.getId());
         List<BCourseStationDto> bCourseStationList = dto.getBCourseStationList();
-        List<BCourseStationPo> bCourseStationPoList = BeanUtil.copyToList(bCourseStationList, BCourseStationPo.class);
-        bCourseStationPoList.forEach(bCourseStationPo -> {
+        String stationName= bCourseStationList.get(0).getName();
+        po.setFirstStationName(stationName);
+        String stationName1 = bCourseStationList.get(bCourseStationList.size()-1).getName();
+        po.setLastStationName(stationName1);
+
+        List<BCourseStationPo> bCourseStationPoList =new ArrayList<>();
+        for(int i = 0; i < bCourseStationList.size(); i++) {
+            BCourseStationDto bCourseStationDto = bCourseStationList.get(i);
+            BCourseStationPo bCourseStationPo = BeanUtil.toBean(bCourseStationDto, BCourseStationPo.class);
             bCourseStationPo.setId(snowflakeUtil.snowflakeId());
             bCourseStationPo.setCourseId(po.getId());
             bCourseStationPo.setCreateTime(new Date());
@@ -200,7 +306,15 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
             bCourseStationPo.setUpdaterId(extInfo.getUserId());
             bCourseStationPo.setCreatorName(extInfo.getUserName());
             bCourseStationPo.setUpdaterName(extInfo.getUserName());
-        });
+            if (i == 0) {
+                bCourseStationPo.setType("0");
+            }else if(i == bCourseStationList.size()-1) {
+                bCourseStationPo.setType("2");
+            }else{
+                bCourseStationPo.setType("1");
+            }
+            bCourseStationPoList.add(bCourseStationPo);
+        }
         bCourseStationService.saveBatch(bCourseStationPoList);
         //处理车辆
         bCourseBusService.deleteByCourseId(po.getId());
@@ -239,4 +353,96 @@ public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCour
         bCourseBusService.remove(queryWrapper2);
 		bCourseInfoMapper.deleteById(id);
     }
+
+    @Override
+    public List<BBusTrackInfoDto> getNearbyRoutes(BigDecimal latitude, BigDecimal longitude, Integer radius) {
+        // 1. 查询附近站点
+        List<BStationInfoDto> nearbyStations = bCourseInfoMapper.findNearbyStations(latitude, longitude, radius);
+        if (CollectionUtil.isEmpty(nearbyStations)) {
+            return Collections.emptyList();
+        }
+        // 2. 查询经过这些站点的路线
+        List<Long> stationIds = nearbyStations.stream()
+                .map(BStationInfoDto::getId)
+                .collect(Collectors.toList());
+
+        List<BCourseInfoVo> routes = bCourseInfoMapper.findRoutesByStations(stationIds);
+
+        for (BCourseInfoVo route : routes) {
+            BBusTrackInfoDto dto = new BBusTrackInfoDto();
+           // vo.setRouteId(route.getId());
+//            vo.setRouteName(route.getName());
+//            vo.setStartStation(route.getStartStation());
+//            vo.setEndStation(route.getEndStation());
+//            vo.setFirstTime(route.getFirstTime());
+//            vo.setLastTime(route.getLastTime());
+//            vo.setPrice(route.getPrice());
+        }
+
+        return null;
+
+//        // 3. 转换并返回结果
+//        return routes.stream().map(route -> {
+//            RouteVO vo = new RouteVO();
+//            vo.setRouteId(route.getId());
+//            vo.setRouteName(route.getName());
+//            vo.setStartStation(route.getStartStation());
+//            vo.setEndStation(route.getEndStation());
+//            vo.setFirstTime(route.getFirstTime());
+//            vo.setLastTime(route.getLastTime());
+//            vo.setPrice(route.getPrice());
+//            // 计算距离最近的站点
+//            StationDTO nearestStation = findNearestStation(
+//                    nearbyStations,
+//                    latitude,
+//                    longitude
+//            );
+//            vo.setNearestStation(nearestStation.getName());
+//            vo.setDistance(calculateDistance(
+//                    latitude,
+//                    longitude,
+//                    nearestStation.getLatitude(),
+//                    nearestStation.getLongitude()
+//            ));
+//            return vo;
+//        }).collect(Collectors.toList());
+    }
+
+    /**
+     * 查找最近的站点
+     */
+    private BStationInfoDto findNearestStation(
+            List<BStationInfoDto> stations,
+            Double latitude,
+            Double longitude) {
+        return stations.stream()
+                .min(Comparator.comparingDouble(station ->
+                        calculateDistance(
+                                latitude,
+                                longitude,
+                                 station.getLatitude().doubleValue(),
+                                station.getLongitude().doubleValue()
+                        )
+                ))
+                .orElse(null);
+    }
+
+    /**
+     * 计算两点之间的距离(米)
+     */
+    private double calculateDistance(
+            Double lat1,
+            Double lng1,
+            Double lat2,
+            Double lng2) {
+        double radLat1 = Math.toRadians(lat1);
+        double radLat2 = Math.toRadians(lat2);
+        double a = radLat1 - radLat2;
+        double b = Math.toRadians(lng1) - Math.toRadians(lng2);
+
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
+                Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
+        s = s * 6378137; // 地球半径
+        return s;
+    }
 }

+ 53 - 10
bus-biz/src/main/resources/mapper/BCourseInfoMapper.xml

@@ -8,37 +8,80 @@
      a.course_name,
      a.course_code,
      a.course_type,
+     a.area,
      COUNT(b.station_id) AS stationNum,
      COUNT(c.bus_id) AS busNum,
-     (select si.`name` from b_course_station cs LEFT JOIN b_station_info si on cs.station_id = si.id where cs.is_delete = 0  order by cs.sort asc LIMIT 1) as firstStationName,
-     (select si.`name` from b_course_station cs LEFT JOIN b_station_info si on cs.station_id = si.id where cs.is_delete = 0  order by cs.sort DESC LIMIT 1) as lastStationName,
-     d.bus_space as busSpace,
+     a.first_station_name as firstStationName,
+     a.last_station_name as lastStationName,
+     a.first_bus_space as firstBusSpace,
      a.status
      from b_course_info a
      LEFT JOIN
      b_course_station b ON a.id = b.course_id AND b.is_delete = 0
      LEFT JOIN
      b_course_bus c ON a.id = c.course_id AND c.is_delete = 0
-     LEFT JOIN
-     b_course_time d ON a.id = c.course_id AND c.is_delete = 0 ORDER BY c.sort LIMIT 1
    <where>
         a.is_delete = 0
        <if test="courseName != null and courseName != ''">
-           a.course_name like concat('%', #{courseName}, '%')
+           and a.course_name like concat('%', #{courseName}, '%')
        </if>
        <if test="courseCode != null and courseCode != ''">
-           a.course_code like concat('%', #{courseCode}, '%')
+           and  a.course_code like concat('%', #{courseCode}, '%')
        </if>
        <if test="courseType != null and courseType != ''">
-           a.course_type = #{courseType}
+           and a.course_type = #{courseType}
        </if>
        <if test="status != null and status != ''">
-           a.status = #{status}
+           and  a.status = #{status}
        </if>
        <if test="id != null and id != ''">
-           a.id = #{id}
+           and a.id = #{id}
        </if>
    </where>
+     GROUP BY
+     a.id
+     ORDER BY a.id dESC
  </select>
 
+    <!-- 查询附近站点 -->
+    <select id="findNearbyStations" resultType="bus.model.dto.BStationInfoDto">
+        SELECT
+        id,
+        name,
+        latitude,
+        longitude,
+        (
+        6378137 * acos(
+        cos(radians(#{latitude})) *
+        cos(radians(latitude)) *
+        cos(radians(longitude) - radians(#{longitude})) +
+        sin(radians(#{latitude})) *
+        sin(radians(latitude))
+        )
+        ) AS distance
+        FROM b_station_info
+        WHERE is_delete = 0
+        HAVING distance &lt; #{radius}
+        ORDER BY distance
+    </select>
+
+    <!-- 查询经过指定站点的路线 -->
+    <select id="findRoutesByStations" resultType="bus.model.vo.BCourseInfoVo">
+        SELECT DISTINCT
+        r.id,
+        r.course_name as courseName
+        FROM
+        b_course_info r
+        INNER JOIN
+        b_course_station rs ON r.id = rs.course_id
+        WHERE
+        r.is_delete = 0
+        AND rs.station_id IN
+        <foreach collection="stationIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        ORDER BY
+        r.id
+    </select>
+
 </mapper>

+ 3 - 4
bus-biz/src/main/resources/mapper/BStationInfoMapper.xml

@@ -24,13 +24,12 @@
     <if test="name != null and name != ''">
       and name like concat('%',#{name},'%')
     </if>
-    <if test="stationLevel != null and stationLevel != ''">
-      and station_level = #{stationLevel}
-    </if>
     <if test="stationStatus != null and stationStatus != ''">
       and station_status = #{stationStatus}
     </if>
-
+    <if test="stationType != null and stationType != ''">
+      and station_type = #{stationType}
+    </if>
     <if test="stationCode != null and stationCode != ''">
       and station_code = #{stationCode}
     </if>

+ 1 - 1
bus-boot/src/main/resources/bootstrap-dev.yaml

@@ -56,7 +56,7 @@ xxl:
     executor:
       appname: demo-executor
       address: ""
-      ip: ""
+      ip: "matrix34.tpddns.cn"
       port: 60066
       logpath: logs
       logretentiondays: 15

+ 5 - 0
bus-common/src/main/java/bus/model/dto/BBusTrackInfoDto.java

@@ -36,6 +36,11 @@ public class BBusTrackInfoDto {
     @ApiModelProperty("详细地址")
     private String detailAddress;
 
+    @ApiModelProperty("标记点名称")
+    private String stationName;
+    @ApiModelProperty("距离")
+    private String distance;
+
     @ApiModelProperty("路线LIST")
     List<BCourseNameInfoDto> bCourseNameInfoList;
 }

+ 6 - 1
bus-common/src/main/java/bus/model/dto/BCourseBusDto.java

@@ -20,5 +20,10 @@ public class BCourseBusDto{
     private Integer sort;
     @ApiModelProperty("备注")
     private String remark;
-
+    @ApiModelProperty("车辆编号 展示用")
+    private String busNo;
+    @ApiModelProperty("驾驶员名称 展示用")
+    private String driverName;
+    @ApiModelProperty("驾驶员号码 展示用")
+    private String driverPhone;
 }

+ 10 - 0
bus-common/src/main/java/bus/model/dto/BCourseInfoDto.java

@@ -3,6 +3,9 @@ package bus.model.dto;
 import bus.model.po.BBusInfoPo;
 import lombok.Data;
 import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.Date;
@@ -24,6 +27,10 @@ public class BCourseInfoDto{
     private String courseCode;
     @ApiModelProperty("地图快照")
     private String mapPicUrl;
+    @ApiModelProperty("区")
+    private String area;
+    @ApiModelProperty("线路标记点LIST")
+    private List<BCoursePointDto> mapPointList;
     @ApiModelProperty("线路类型 0单层专线,1闭环专线")
     private String courseType;
     @ApiModelProperty("票价类型 0固定票价 1参考票价")
@@ -34,11 +41,14 @@ public class BCourseInfoDto{
     private String status;
 
     @ApiModelProperty("时刻LIST")
+    @NotEmpty(message = "时刻列表不能为空")
     List<BCourseTimeDto> bCourseTimeList;
 
     @ApiModelProperty("标志点LIST")
+    @NotEmpty(message = "标志点列表不能为空")
     List<BCourseStationDto> bCourseStationList;
 
     @ApiModelProperty("车辆LIST")
+    @NotEmpty(message = "车辆列表不能为空")
     List<BCourseBusDto> bCourseBusList;
 }

+ 21 - 0
bus-common/src/main/java/bus/model/dto/BCoursePointDto.java

@@ -0,0 +1,21 @@
+package bus.model.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+* @Program: bus
+* @Description: 描述
+* @Author: zy
+* @Date: 2025-03-02 19:53:50
+**/
+@Data
+public class BCoursePointDto {
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+}

+ 17 - 0
bus-common/src/main/java/bus/model/dto/BCourseStationDto.java

@@ -2,6 +2,8 @@ package bus.model.dto;
 
 import lombok.Data;
 import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.Date;
 /**
@@ -16,10 +18,25 @@ public class BCourseStationDto{
     private String id;
     @ApiModelProperty("标志点id")
     private String stationId;
+    @ApiModelProperty("标志点名称")
+    private String name;
     @ApiModelProperty("排序")
     private Integer sort;
     @ApiModelProperty("类型 0始发 1中途 2终点")
     private String type;
     @ApiModelProperty("备注")
     private String remark;
+
+    @ApiModelProperty("标志点类型 展示用")
+    private String stationType;
+    @ApiModelProperty("状态 0正常 1维护 2禁用 展示用")
+    private String stationStatus;
+    @ApiModelProperty("详细地址 展示用")
+    private String detailAddress;
+    @ApiModelProperty("标志点编号 展示用")
+    private String stationCode;
+    @ApiModelProperty("经度 展示用")
+    private BigDecimal longitude;
+    @ApiModelProperty("纬度 展示用")
+    private BigDecimal latitude;
 }

+ 1 - 1
bus-common/src/main/java/bus/model/dto/BCourseTimeDto.java

@@ -18,7 +18,7 @@ public class BCourseTimeDto{
     private String busSpace;
     @ApiModelProperty("排序")
     private Integer sort;
-    @ApiModelProperty("类型 0始发 1中途 2终点")
+    @ApiModelProperty("类型 0始发 1中途 ")
     private String type;
     @ApiModelProperty("备注")
     private String remark;

+ 4 - 3
bus-common/src/main/java/bus/model/dto/BStationInfoDto.java

@@ -17,13 +17,15 @@ import java.util.List;
 @Data
 public class BStationInfoDto{
     @ApiModelProperty("id")
-    private String id;
+    private Long id;
     @ApiModelProperty("标志点名称")
     private String name;
     @ApiModelProperty("标志点类型")
     private String stationType;
     @ApiModelProperty("状态 0正常 1维护 2禁用")
     private String stationStatus;
+    @ApiModelProperty("详细地址")
+    private String detailAddress;
     @ApiModelProperty("标志点编号")
     private String stationCode;
     @ApiModelProperty("介绍")
@@ -34,8 +36,7 @@ public class BStationInfoDto{
     private BigDecimal longitude;
     @ApiModelProperty("纬度")
     private BigDecimal latitude;
-    @ApiModelProperty("详细地址")
-    private String detailAddress;
+
     @ApiModelProperty("省份")
     private String province;
     @ApiModelProperty("市")

+ 8 - 0
bus-common/src/main/java/bus/model/po/BCourseInfoPo.java

@@ -25,6 +25,14 @@ public class BCourseInfoPo{
     private String courseType;
     @ApiModelProperty("地图快照")
     private String mapPicUrl;
+    @ApiModelProperty("路线点")
+    private String mapPoint;
+    private String firstStationName;
+    private String firstStationId;
+    private String lastStationName;
+    private String lastStationId;
+    private String firstBusSpace;
+    private String area;
     private String ticketType;
     private BigDecimal ticketAmount;
     private String status;

+ 3 - 1
bus-common/src/main/java/bus/model/vo/BCourseInfoVo.java

@@ -25,6 +25,8 @@ public class BCourseInfoVo extends AbstractBaseVO{
     private String courseType;
     @ApiModelProperty("路线状态 0正常 1维护 2禁用")
     private String status;
+    @ApiModelProperty("区")
+    private String area;
     @ApiModelProperty("标志点数量")
     private String stationNum;
     @ApiModelProperty("车辆数量")
@@ -34,6 +36,6 @@ public class BCourseInfoVo extends AbstractBaseVO{
     @ApiModelProperty("终点标志点")
     private String lastStationName;
     @ApiModelProperty("始发时间")
-    private String busSpace;
+    private String firstBusSpace;
 
 }

+ 4 - 2
bus-web/src/main/java/bus/controller/biz/BCourseInfoController.java

@@ -10,9 +10,11 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import com.qzwisdom.qzframework.core.tool.base.controller.BaseController;
 
+import javax.validation.Valid;
 
 
 /**
@@ -51,7 +53,7 @@ public class BCourseInfoController implements BaseController {
      */
     @ApiOperation("保存")
     @PostMapping(value = "save")
-    public String save(@RequestBody BCourseInfoDto dto){
+    public String save(@RequestBody @Valid BCourseInfoDto dto){
 		bCourseInfoService.save(dto);
         return "保存成功";
     }
@@ -75,7 +77,7 @@ public class BCourseInfoController implements BaseController {
      */
     @ApiOperation("修改")
     @PostMapping(value = "update")
-    public String update(@RequestBody BCourseInfoDto dto){
+    public String update(@RequestBody @Valid  BCourseInfoDto dto){
 		bCourseInfoService.update(dto);
         return "修改成功";
     }

+ 45 - 0
bus-web/src/main/java/bus/controller/biz/WChatUserController.java

@@ -1,13 +1,20 @@
 package bus.controller.biz;
 
 import bus.model.dto.req.WxLoginReq;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import com.alibaba.fastjson.JSON;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageSerializable;
 import bus.model.dto.WChatUserDto;
 import bus.model.dto.page.WChatUserPageDto;
 import bus.model.vo.WChatUserVo;
 import bus.service.WChatUserService;
+import com.orcas.common.model.JsonResponse;
 import com.orcas.common.sso.model.SsoUserAuthDto;
+import com.qzwisdom.qzframework.core.tool.exception.BusinessException;
+import com.sun.jndi.toolkit.url.UrlUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
@@ -17,6 +24,8 @@ import com.qzwisdom.qzframework.core.tool.base.controller.BaseController;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
 
 
 /**
@@ -35,6 +44,12 @@ public class WChatUserController implements BaseController {
     @Autowired
     private WChatUserService wChatUserService;
 
+    private static final String appId = "wx93b327996c5a3839";
+    private static final String appSecret = "491d369f6ca0bc6b9b49ec2e61c3ef4b";
+    private static  final String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session";
+    private static final int TIME_OUT  = 3000;
+
+    private static final String ERROR_CODE_STR = "errcode";
 
     @RequestMapping(value = "/auto/login", method = RequestMethod.POST)
     @ApiOperation(value = "小程序登陆调用")
@@ -44,6 +59,36 @@ public class WChatUserController implements BaseController {
         return ssoUserAuthDto;
     }
 
+    @RequestMapping(value = "/getXcxOpenId", method = RequestMethod.GET)
+    @ApiOperation(value = "微信小程序获取OpenId")
+    public Map<String,String> getXcxOpenId(@RequestParam(required = true) String code){
+        if(StrUtil.isBlank(code)){
+            throw new BusinessException("code不能为空");
+        }
+        String params = "" +
+                "?appid=" + appId +
+                "&secret=" + appSecret +
+                "&js_code=" + code +
+                "&grant_type=authorization_code";
+        String json = HttpUtil.get(OPENID_URL+params, TIME_OUT);
+        if(StrUtil.isBlank(json)){
+            throw new BusinessException("无法获取微信登录状态:JSON获取失败");
+        }
+        JSONObject jsonObj = new JSONObject(json);
+        if(jsonObj.get(ERROR_CODE_STR)!=null && jsonObj.get(ERROR_CODE_STR,Integer.class)!=0){
+            throw new BusinessException("小程序登录失败");
+        }
+        Map<String,String> map = new HashMap<>();
+        String openId = (String)jsonObj.get("openid");
+        String sessionKey = (String)jsonObj.get("session_key");
+        Object unionId = jsonObj.get("unionid");
+        map.put("openId",openId);
+        map.put("sessionKey",sessionKey);
+        map.put("unionId",unionId!=null?String.valueOf(unionId):"");
+        return map;
+    }
+
+
 
     /**
      * 详情