获取用户当前位置的运营区及站点

This commit is contained in:
yanglei 2026-01-08 09:24:47 +08:00
parent acc4af8855
commit 379697995c
8 changed files with 103 additions and 33 deletions

View File

@ -128,7 +128,8 @@ public interface OperationsFeignClient {
*/ */
@GetMapping("/ebikeRegion/api/getRegionByLocation") @GetMapping("/ebikeRegion/api/getRegionByLocation")
JsonResult<FeignEbikeRegionVo> getRegionByLocation(@RequestParam("lng") double lng, JsonResult<FeignEbikeRegionVo> getRegionByLocation(@RequestParam("lng") double lng,
@RequestParam("lat") double lat); @RequestParam("lat") double lat,
@RequestParam("radius") double radius);
/** /**
* 生成退款审核单 * 生成退款审核单

View File

@ -271,10 +271,11 @@ public class EbikeRegionController {
*/ */
@GetMapping("/api/getRegionByLocation") @GetMapping("/api/getRegionByLocation")
public JsonResult<?> getRegionByLocation(@RequestParam("lng") double lng, public JsonResult<?> getRegionByLocation(@RequestParam("lng") double lng,
@RequestParam("lat") double lat) { @RequestParam("lat") double lat,
@RequestParam("radius") double radius) {
GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
Point location = geometryFactory.createPoint(new Coordinate(lng, lat)); Point location = geometryFactory.createPoint(new Coordinate(lng, lat));
FeignEbikeRegionVo region = ebikeRegionService.getRegionByLocation(location); FeignEbikeRegionVo region = ebikeRegionService.getRegionByLocation(location, radius);
return JsonResult.success(region); return JsonResult.success(region);
} }
} }

View File

@ -31,11 +31,19 @@ public interface EbikeRegionMapper extends BaseMapper<EbikeRegion> {
*/ */
List<EbikeRegion> findAllRegionsOrderByDistance(Point point); List<EbikeRegion> findAllRegionsOrderByDistance(Point point);
/**
* 根据当前位置查询当前运营区及站点
*
* @param point 用户当前位置
* @return 运营区信息及站点信息
*/
FeignEbikeRegionVo findCurrentRegion(Point point, double radius);
/** /**
* 根据当前位置查询当前运营区 * 根据当前位置查询当前运营区
* *
* @param point 用户当前位置 * @param point 用户当前位置
* @return 运营区信息 * @return 运营区信息
*/ */
FeignEbikeRegionVo findCurrentRegion(Point point); EbikeRegion findCurrentPointRegion(Point point);
} }

View File

@ -45,5 +45,5 @@ public interface EbikeRegionService extends IService<EbikeRegion> {
* @param point 当前位置 * @param point 当前位置
* @return 运营区信息 * @return 运营区信息
*/ */
FeignEbikeRegionVo getRegionByLocation(Point point); FeignEbikeRegionVo getRegionByLocation(Point point,double radius);
} }

View File

@ -24,6 +24,8 @@ import org.locationtech.jts.geom.Point;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
import static com.cdzy.operations.model.entity.table.EbikeOperationConfigTableDef.EBIKE_OPERATION_CONFIG; import static com.cdzy.operations.model.entity.table.EbikeOperationConfigTableDef.EBIKE_OPERATION_CONFIG;
import static com.cdzy.operations.model.entity.table.EbikeOperationLockConfigTableDef.EBIKE_OPERATION_LOCK_CONFIG; import static com.cdzy.operations.model.entity.table.EbikeOperationLockConfigTableDef.EBIKE_OPERATION_LOCK_CONFIG;
import static com.cdzy.operations.model.entity.table.EbikeOperationReturnConfigTableDef.EBIKE_OPERATION_RETURN_CONFIG; import static com.cdzy.operations.model.entity.table.EbikeOperationReturnConfigTableDef.EBIKE_OPERATION_RETURN_CONFIG;
@ -154,7 +156,11 @@ public class EbikeRegionServiceImpl extends ServiceImpl<EbikeRegionMapper, Ebike
} }
@Override @Override
public FeignEbikeRegionVo getRegionByLocation(Point point) { public FeignEbikeRegionVo getRegionByLocation(Point point, double radius) {
return this.mapper.findCurrentRegion(point); FeignEbikeRegionVo currentRegion = this.mapper.findCurrentRegion(point, radius);
if (Objects.isNull(currentRegion)) {
throw new EbikeException("获取当前运营区失败");
}
return currentRegion;
} }
} }

View File

@ -14,7 +14,6 @@ import com.cdzy.operations.model.entity.EbikeReportRecordFile;
import com.cdzy.operations.model.vo.EbikeSiteVo; import com.cdzy.operations.model.vo.EbikeSiteVo;
import com.cdzy.operations.service.EbikeReportRecordService; import com.cdzy.operations.service.EbikeReportRecordService;
import com.cdzy.operations.service.EbikeSiteService; import com.cdzy.operations.service.EbikeSiteService;
import com.ebike.feign.model.vo.FeignEbikeRegionVo;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -47,7 +46,7 @@ public class EbikeReportRecordServiceImpl extends ServiceImpl<EbikeReportRecordM
@Transactional @Transactional
@Override @Override
public void saveReportRecord(EbikeReportRecordDto reportRecordDto) { public void saveReportRecord(EbikeReportRecordDto reportRecordDto) {
FeignEbikeRegionVo currentRegion = ebikeRegionMapper.findCurrentRegion(reportRecordDto.getLocation()); EbikeRegion currentRegion = ebikeRegionMapper.findCurrentPointRegion(reportRecordDto.getLocation());
if (Objects.isNull(currentRegion)) { if (Objects.isNull(currentRegion)) {
// 获取运营区为空直接拒绝掉当前申请 // 获取运营区为空直接拒绝掉当前申请
throw new EbikeException("当前位置不在任何运营区内,无法申请"); throw new EbikeException("当前位置不在任何运营区内,无法申请");

View File

@ -57,14 +57,64 @@
</resultMap> </resultMap>
<select id="findCurrentRegion" resultMap="FeignEbikeRegionVoMap"> <select id="findCurrentRegion" resultMap="FeignEbikeRegionVoMap">
WITH nearest_region_in_radius AS (
-- 先获取半径范围内的区域
SELECT
r.*,
ST_Distance(
ST_SetSRID(r.region_polygon::geometry, 4326)::geography,
ST_SetSRID(ST_MakePoint(#{point.x}, #{point.y}), 4326)::geography
) AS distance_meters,
ST_Contains(
ST_SetSRID(r.region_polygon::geometry, 4326),
ST_SetSRID(ST_MakePoint(#{point.x}, #{point.y}), 4326)
) AS is_within_region
FROM ebike_region r
WHERE r.is_deleted IS NOT TRUE
AND r.status = 1
AND ST_DWithin(
ST_SetSRID(r.region_polygon::geometry, 4326)::geography,
ST_SetSRID(ST_MakePoint(#{point.x}, #{point.y}), 4326)::geography,
#{radius}
)
ORDER BY is_within_region DESC, distance_meters
LIMIT 1
),
nearest_region_overall AS (
-- 如果没有半径范围内的,获取所有区域中最近的
SELECT SELECT
r.region_id, r.*,
r.operator_id, ST_Distance(
r.region_name, ST_SetSRID(r.region_polygon::geometry, 4326)::geography,
r.region_simple_name, ST_SetSRID(ST_MakePoint(#{point.x}, #{point.y}), 4326)::geography
r.region_polygon, ) AS distance_meters,
r.site_num, ST_Contains(
r.status, ST_SetSRID(r.region_polygon::geometry, 4326),
ST_SetSRID(ST_MakePoint(#{point.x}, #{point.y}), 4326)
) AS is_within_region
FROM ebike_region r
WHERE r.is_deleted IS NOT TRUE
AND r.status = 1
ORDER BY is_within_region DESC, distance_meters
LIMIT 1
),
final_region AS (
SELECT * FROM nearest_region_in_radius
UNION ALL
SELECT * FROM nearest_region_overall
WHERE NOT EXISTS (SELECT 1 FROM nearest_region_in_radius)
LIMIT 1
)
SELECT
fr.region_id,
fr.operator_id,
fr.region_name,
fr.region_simple_name,
fr.region_polygon,
fr.site_num,
fr.status,
fr.distance_meters,
fr.is_within_region,
s.site_id, s.site_id,
s.site_name, s.site_name,
s.operator_id AS site_operator_id, s.operator_id AS site_operator_id,
@ -72,21 +122,20 @@
s.site_polygon, s.site_polygon,
s.site_type, s.site_type,
s.is_deleted AS site_is_deleted s.is_deleted AS site_is_deleted
FROM ( FROM final_region fr
SELECT region_id LEFT JOIN ebike_site s ON fr.region_id = s.region_id
FROM ebike_region
WHERE is_deleted IS NOT TRUE
AND status = 1
AND ST_Contains(
ST_SetSRID(region_polygon::geometry, 4326),
ST_SetSRID(ST_MakePoint(#{x}, #{y}), 4326)
)
ORDER BY region_id
LIMIT 1
) fr
JOIN ebike_region r ON fr.region_id = r.region_id
LEFT JOIN ebike_site s ON r.region_id = s.region_id
AND s.is_deleted IS NOT TRUE AND s.is_deleted IS NOT TRUE
AND s.site_type = 1 AND s.site_type = 1
</select> </select>
<select id="findCurrentPointRegion" resultType="com.cdzy.operations.model.entity.EbikeRegion">
SELECT *
FROM ebike_region
WHERE is_deleted IS NOT TRUE
AND ST_Contains(
ST_SetSRID(region_polygon::geometry, 4326),
ST_SetSRID(ST_MakePoint(#{x}, #{y}), 4326)
)
LIMIT 1
</select>
</mapper> </mapper>

View File

@ -20,7 +20,12 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map; import java.util.Map;
@ -202,8 +207,9 @@ public class EbikeUserController {
*/ */
@GetMapping("getRegionByLocation") @GetMapping("getRegionByLocation")
public JsonResult<?> getRegionByLocation(@RequestParam("lng") double lng, public JsonResult<?> getRegionByLocation(@RequestParam("lng") double lng,
@RequestParam("lat") double lat) { @RequestParam("lat") double lat,
JsonResult<FeignEbikeRegionVo> jsonResult = operationsFeignClient.getRegionByLocation(lng, lat); @RequestParam("radius") double radius) {
JsonResult<FeignEbikeRegionVo> jsonResult = operationsFeignClient.getRegionByLocation(lng, lat, radius);
if (jsonResult.getCode() != Code.SUCCESS) { if (jsonResult.getCode() != Code.SUCCESS) {
throw new EbikeException(jsonResult.getMessage()); throw new EbikeException(jsonResult.getMessage());
} }