半径范围内车辆查询

This commit is contained in:
attiya 2025-11-07 17:04:22 +08:00
parent f4ce280a4c
commit 068aecc39d
9 changed files with 154 additions and 7 deletions

View File

@ -11,8 +11,8 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* @author: yanglei
* @since: 2025-10-21 11:44
* @author yanglei
* @since 2025-10-21 11:44
*/
@FeignClient(name = "ebike-operations", configuration = {ExampleFeignConfiguration.class, FeignTokenInterceptor.class})
public interface OperationsFeignClient {

View File

@ -3,15 +3,19 @@ package com.cdzy.operations.controller;
import com.cdzy.common.model.request.PageParam;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.operations.model.dto.EbikeBikeInfoDto;
import com.cdzy.operations.model.dto.EbikeDto;
import com.cdzy.operations.model.vo.EbikeBatchLaunchVo;
import com.cdzy.operations.model.vo.EbikeBatchUnLaunchVo;
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
import com.cdzy.operations.model.vo.EbikeBikeRadiusVo;
import com.cdzy.operations.service.EbikeBikeInfoService;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 车辆基本信息 控制层
*
@ -84,4 +88,15 @@ public class EbikeBikeInfoController {
ebikeBikeInfoService.batchUnLaunch(launchVo);
return JsonResult.success();
}
/**
* 用户半径范围内车辆
*
* @return 结果
*/
@PostMapping("/api/userRadiusList")
public JsonResult<?> userRadiusList(@Validated @RequestBody EbikeBikeRadiusVo radiusVo) {
List<EbikeDto> list = ebikeBikeInfoService.userRadiusList(radiusVo);
return JsonResult.success(list);
}
}

View File

@ -23,7 +23,7 @@ public class PGpointSerializer extends JsonSerializer<PGpoint> {
gen.writeStartObject();
gen.writeStringField("type","point");
gen.writeNumberField("longitude",point.x);
gen.writeNumberField("latitude",point.x);
gen.writeNumberField("latitude",point.y);
// gen.writeArrayFieldStart("coordinates");
// gen.writeNumber(point.x);
// gen.writeNumber(point.y);

View File

@ -1,8 +1,10 @@
package com.cdzy.operations.mapper;
import com.cdzy.operations.model.dto.EbikeDto;
import com.mybatisflex.core.BaseMapper;
import com.cdzy.operations.model.entity.EbikeBikeInfo;
import org.apache.ibatis.annotations.Param;
import org.postgresql.geometric.PGpoint;
import org.postgresql.geometric.PGpolygon;
import java.util.List;
@ -22,4 +24,13 @@ public interface EbikeBikeInfoMapper extends BaseMapper<EbikeBikeInfo> {
*/
List<EbikeBikeInfo> selectPolygonGeometry(@Param("polygon") PGpolygon polygon);
/**
* 查询半径范围内的车辆带距离排序
* @param centerPoint 中心点坐标
* @param radiusMeters 半径距离
* @return 按距离排序的车辆列表
*/
List<EbikeDto> selectRadiusGeometryWithOrder(@Param("centerPoint") PGpoint centerPoint,
@Param("radius") double radiusMeters);
}

View File

@ -0,0 +1,35 @@
package com.cdzy.operations.model.dto;
import com.cdzy.operations.handler.PGpointDeserializer;
import com.cdzy.operations.handler.PGpointSerializer;
import com.cdzy.operations.handler.PGpointTypeHandler;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mybatisflex.annotation.Column;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.postgresql.geometric.PGpoint;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EbikeDto implements Serializable {
/**
* 车辆编号与车辆二维码编号相同
*/
private String bikeCode;
/**
* 定位
*/
@Column(typeHandler = PGpointTypeHandler.class)
@JsonSerialize(using = PGpointSerializer.class)
@JsonDeserialize(using = PGpointDeserializer.class)
private PGpoint location;
}

View File

@ -0,0 +1,51 @@
package com.cdzy.operations.model.vo;
import com.cdzy.operations.handler.PGpointDeserializer;
import com.cdzy.operations.handler.PGpointSerializer;
import com.cdzy.operations.handler.PGpointTypeHandler;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mybatisflex.annotation.Column;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.postgresql.geometric.PGpoint;
import java.io.Serial;
import java.io.Serializable;
/**
* 实体类
*
* @author attiya
* @since 2025-10-21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeBikeRadiusVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户所在坐标
*/
@Column(typeHandler = PGpointTypeHandler.class)
@JsonSerialize(using = PGpointSerializer.class)
@JsonDeserialize(using = PGpointDeserializer.class)
@NotNull(message = "用户所在坐标不能为空")
private PGpoint point;
/**
* 用户所在坐标
*/
@NotNull(message = "半径不能为空")
private Float radius;
}

View File

@ -2,10 +2,12 @@ package com.cdzy.operations.service;
import com.cdzy.common.model.request.PageParam;
import com.cdzy.operations.model.dto.EbikeBikeInfoDto;
import com.cdzy.operations.model.dto.EbikeDto;
import com.cdzy.operations.model.entity.EbikeBikeInfo;
import com.cdzy.operations.model.vo.EbikeBatchLaunchVo;
import com.cdzy.operations.model.vo.EbikeBatchUnLaunchVo;
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
import com.cdzy.operations.model.vo.EbikeBikeRadiusVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import org.postgresql.geometric.PGpolygon;
@ -58,4 +60,11 @@ public interface EbikeBikeInfoService extends IService<EbikeBikeInfo> {
* @param launchVo 下架参数
*/
void batchUnLaunch(EbikeBatchUnLaunchVo launchVo);
/**
* 车辆
* @param radiusVo 半径信息
* @return 车辆列表
*/
List<EbikeDto> userRadiusList(EbikeBikeRadiusVo radiusVo);
}

View File

@ -6,11 +6,9 @@ import com.cdzy.common.model.request.PageParam;
import com.cdzy.operations.enums.*;
import com.cdzy.operations.mapper.*;
import com.cdzy.operations.model.dto.EbikeBikeInfoDto;
import com.cdzy.operations.model.dto.EbikeDto;
import com.cdzy.operations.model.entity.*;
import com.cdzy.operations.model.vo.EbikeBatchLaunchVo;
import com.cdzy.operations.model.vo.EbikeBatchUnLaunchVo;
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
import com.cdzy.operations.model.vo.EbikeInventoryVo;
import com.cdzy.operations.model.vo.*;
import com.cdzy.operations.service.EbikeBikeInfoService;
import com.cdzy.operations.service.EbikeInventoryRecordService;
import com.cdzy.operations.service.EbikeInventoryService;
@ -243,4 +241,9 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
.update();
}
@Override
public List<EbikeDto> userRadiusList(EbikeBikeRadiusVo radiusVo) {
return this.mapper.selectRadiusGeometryWithOrder(radiusVo.getPoint(),radiusVo.getRadius()*1000);
}
}

View File

@ -4,9 +4,32 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cdzy.operations.mapper.EbikeBikeInfoMapper">
<resultMap id="EbikeDtoMap" type="com.cdzy.operations.model.dto.EbikeDto">
<result column="bike_code" property="bikeCode"/>
<result column="location" property="location" typeHandler="com.cdzy.operations.handler.PGpointTypeHandler"/>
</resultMap>
<select id="selectPolygonGeometry" resultType="com.cdzy.operations.model.entity.EbikeBikeInfo">
SELECT *
FROM ebike_bike_info
WHERE ST_Within(location::geometry, #{polygon}::geometry)
</select>
<!-- 半径查询(带距离排序) -->
<select id="selectRadiusGeometryWithOrder" resultMap="EbikeDtoMap">
SELECT
ebike_bike_info.bike_code,
ebike_bike_info.location,
ST_Distance(
ST_SetSRID(ST_MakePoint(ST_X(location::geometry), ST_Y(location::geometry)), 4326)::geography,
ST_SetSRID(ST_MakePoint(#{centerPoint.x}, #{centerPoint.y}), 4326)::geography
) as distance
FROM ebike_bike_info
WHERE ST_DWithin(
ST_SetSRID(ST_MakePoint(ST_X(location::geometry), ST_Y(location::geometry)), 4326)::geography,
ST_SetSRID(ST_MakePoint(#{centerPoint.x}, #{centerPoint.y}), 4326)::geography,
#{radius}
)
ORDER BY distance ASC
</select>
</mapper>