OpenApiController.java
4.19 KB
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
package com.diligrp.rider.controller;
import com.diligrp.rider.common.exception.BizException;
import com.diligrp.rider.common.result.Result;
import com.diligrp.rider.dto.DeliveryFeeCalcDTO;
import com.diligrp.rider.dto.OpenDeliveryFeeCalcDTO;
import com.diligrp.rider.dto.OpenRouteCalcDTO;
import com.diligrp.rider.entity.OpenApp;
import com.diligrp.rider.service.DeliveryFeeService;
import com.diligrp.rider.service.OpenAppService;
import com.diligrp.rider.service.amap.AmapRouteClient;
import com.diligrp.rider.util.GeoUtil;
import com.diligrp.rider.vo.DeliveryFeeResultVO;
import com.diligrp.rider.vo.RouteCalcVO;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
/**
* 开放平台对外接口
* 路径前缀 /api/open/** 受 OpenApiInterceptor 签名鉴权保护
* 第三方系统需携带 X-App-Key / X-Timestamp / X-Nonce / X-Sign 请求头
*/
@RestController
@RequestMapping("/api/open")
@RequiredArgsConstructor
public class OpenApiController {
private final DeliveryFeeService deliveryFeeService;
private final OpenAppService openAppService;
private final AmapRouteClient amapRouteClient;
/**
* 计算配送费(对外开放版)
* cityId 由 AppKey 绑定的租户自动确定,不信任外部传参
*/
@PostMapping("/delivery/fee/calc")
public Result<DeliveryFeeResultVO> calcFee(@Valid @RequestBody OpenDeliveryFeeCalcDTO dto,
HttpServletRequest request) {
DeliveryFeeCalcDTO calcDTO = new DeliveryFeeCalcDTO();
calcDTO.setCityId(resolveCityId(request));
calcDTO.setOrderType(dto.getOrderType());
calcDTO.setStartLng(dto.getStartLng());
calcDTO.setStartLat(dto.getStartLat());
calcDTO.setEndLng(dto.getEndLng());
calcDTO.setEndLat(dto.getEndLat());
calcDTO.setWeight(dto.getWeight());
calcDTO.setPieces(dto.getPieces());
calcDTO.setServiceTime(dto.getServiceTime());
return Result.success(deliveryFeeService.calcFee(calcDTO));
}
/**
* 检查城市服务是否开通
* cityId 由 AppKey 绑定的租户自动确定
*/
@GetMapping("/delivery/check")
public Result<Boolean> check(@RequestParam int orderType, HttpServletRequest request) {
return Result.success(deliveryFeeService.isServiceEnabled(resolveCityId(request), orderType));
}
/**
* 路线计算:传入起止经纬度,返回距离(米)与导航耗时(秒)。
* - distance 始终有值:优先高德电动车路径距离,失败时回退到直线距离
* - duration 高德未命中时为 null
*/
@PostMapping("/route/calc")
public Result<RouteCalcVO> routeCalc(@Valid @RequestBody OpenRouteCalcDTO dto) {
Optional<AmapRouteClient.AmapRoute> route = amapRouteClient.getElectrobikeRoute(
dto.getStartLng(), dto.getStartLat(), dto.getEndLng(), dto.getEndLat());
if (route.isPresent()) {
return Result.success(new RouteCalcVO(route.get().distanceMeters(), route.get().durationSeconds()));
}
double km;
try {
km = GeoUtil.calcDistanceKm(
Double.parseDouble(dto.getStartLat()),
Double.parseDouble(dto.getStartLng()),
Double.parseDouble(dto.getEndLat()),
Double.parseDouble(dto.getEndLng()));
} catch (Exception e) {
throw new BizException("起止经纬度格式错误");
}
int distanceMeters = (int) Math.round(km * 1000);
return Result.success(new RouteCalcVO(distanceMeters, null));
}
private Long resolveCityId(HttpServletRequest request) {
String appKey = request.getHeader("X-App-Key");
OpenApp app = openAppService.getByAppKey(appKey);
if (app == null || app.getStatus() != 1) {
throw new BizException("应用不存在或已禁用");
}
if (app.getCityId() == null || app.getCityId() < 1) {
throw new BizException("该应用未绑定租户,请联系平台管理员");
}
return app.getCityId();
}
}