# TSP 平台对接场景设计文档

## 一、概述

本文档定义了车辆服务（Vehicle Service）与外部 TSP（Telematics Service Provider）平台对接的完整链路设计，包括同步/异步场景划分、调用路径选择等。

## 二、架构说明

### 2.1 服务模块说明

- **Gateway（网关）**：统一入口，路由分发
- **Business Service（业务服务）**：处理业务逻辑，聚合多个服务
- **Vehicle Service（车辆服务）**：车辆相关核心服务，直接对接 TSP

### 2.2 调用路径

#### 路径一：客户端 → Gateway → Business Service → Vehicle Service → TSP
**适用场景**：需要业务逻辑处理、数据聚合、权限校验等

#### 路径二：客户端 → Gateway → Vehicle Service → TSP
**适用场景**：纯车辆操作，无需业务逻辑，性能要求高

---

## 三、同步回传场景（HTTP/Feign 同步调用）

### 3.1 场景特征
- **实时性要求高**：用户需要立即知道操作结果
- **操作简单快速**：TSP 处理时间短（通常 < 3秒）
- **结果明确**：成功/失败状态清晰

### 3.2 具体场景列表

#### 3.2.1 车辆控制类（必须同步）

| 场景 | 接口路径 | 调用链路 | TSP 指令 | 说明 |
|------|---------|---------|---------|------|
| **开锁** | `/app/vehicle/control/unlock` | 路径一 | `UNLOCK` | 用户点击开锁，需立即反馈成功/失败 |
| **关锁** | `/app/vehicle/control/lock` | 路径一 | `LOCK` | 用户点击关锁，需立即反馈 |
| **启动** | `/app/vehicle/control/start` | 路径一 | `START` | 远程启动车辆，需立即反馈 |
| **熄火** | `/app/vehicle/control/stop` | 路径一 | `STOP` | 远程熄火，需立即反馈 |
| **鸣笛** | `/app/vehicle/control/horn` | 路径一 | `HORN` | 寻车鸣笛，需立即反馈 |
| **灯光** | `/app/vehicle/control/light` | 路径一 | `LIGHT` | 灯光控制，需立即反馈 |

**实现方式**：
```java
// Vehicle Service 中实现
@Service
public class VehicleControlServiceImpl {
    
    @Resource
    private TspApiClient tspApiClient; // Feign 客户端
    
    public CommonResult<Boolean> controlVehicle(VehicleControlReqDTO reqDTO) {
        // 1. 同步调用 TSP
        TspControlResponse response = tspApiClient.sendControlCommand(
            convertToTspRequest(reqDTO)
        );
        
        // 2. 处理响应（立即返回）
        if (response.isSuccess()) {
            // 更新本地状态
            updateLocalStatus(reqDTO.getVehicleId(), response);
            return success(true);
        } else {
            // 记录失败原因
            log.error("TSP控制失败: {}", response.getErrorMsg());
            return error(response.getErrorCode(), response.getErrorMsg());
        }
    }
}
```

**链路图**：
```
客户端 → Gateway → Business Service → Vehicle Service → [HTTP同步] → TSP平台
                                                              ↓
                                                        立即返回结果
                                                              ↓
客户端 ← Gateway ← Business Service ← Vehicle Service ← [直接返回]
```

---

#### 3.2.2 车辆状态查询类（必须同步）

| 场景 | 接口路径 | 调用链路 | TSP 接口 | 说明 |
|------|---------|---------|---------|------|
| **查询实时状态** | `/app/vehicle/status` | 路径一 | `GET_STATUS` | 查询电量、里程、速度等，需实时返回 |
| **查询位置信息** | `/app/vehicle/location` | 路径一 | `GET_LOCATION` | 查询车辆GPS位置，需实时返回 |
| **查询车辆信息** | `/app/vehicle/get` | 路径一 | `GET_VEHICLE_INFO` | 查询车辆基本信息，可能从TSP获取 |

**实现方式**：
```java
@Service
public class VehicleStatusServiceImpl {
    
    @Resource
    private TspApiClient tspApiClient;
    
    public VehicleStatusRespDTO getVehicleStatus(Long vehicleId) {
        // 1. 先查本地缓存（如果有）
        VehicleStatusDO localStatus = vehicleStatusMapper.selectByVehicleId(vehicleId);
        
        // 2. 如果本地数据过期（>5分钟），从TSP实时查询
        if (localStatus == null || isExpired(localStatus)) {
            TspStatusResponse tspResponse = tspApiClient.getRealTimeStatus(vehicleId);
            // 更新本地并返回
            return updateAndConvert(tspResponse);
        }
        
        return convert(localStatus);
    }
}
```

**链路图**：
```
客户端 → Gateway → Business Service → Vehicle Service → [HTTP同步] → TSP平台
                                                              ↓
                                                        实时状态数据
                                                              ↓
客户端 ← Gateway ← Business Service ← Vehicle Service ← [立即返回]
```

---

#### 3.2.3 车辆绑定/解绑类（必须同步）

| 场景 | 接口路径 | 调用链路 | TSP 接口 | 说明 |
|------|---------|---------|---------|------|
| **绑定车辆** | `/app/vehicle/bind` | 路径一 | `BIND_VEHICLE` | 绑定车辆到TSP，需立即确认 |
| **解绑车辆** | `/app/vehicle/unbind` | 路径一 | `UNBIND_VEHICLE` | 解绑车辆，需立即确认 |

**说明**：绑定/解绑操作需要 TSP 立即返回结果，因为涉及权限变更。

---

### 3.3 同步场景总结

| 场景类型 | 数量 | 特点 | 超时时间 |
|---------|------|------|---------|
| 车辆控制 | 6个 | 用户操作，需立即反馈 | 5秒 |
| 状态查询 | 3个 | 实时数据，需立即返回 | 3秒 |
| 绑定操作 | 2个 | 权限变更，需立即确认 | 5秒 |
| **总计** | **11个** | - | - |

---

## 四、异步回传场景（Kafka 消息队列）

### 4.1 场景特征
- **处理时间长**：TSP 处理时间 > 5秒
- **高并发**：大量数据上报，需要解耦
- **结果推送**：通过 WebSocket 推送给客户端，不需要 HTTP 响应

### 4.2 具体场景列表

#### 4.2.1 TSP 主动状态上报（必须异步）

| 场景 | 触发方式 | Kafka Topic | 说明 |
|------|---------|------------|------|
| **车辆状态上报** | TSP 定时推送 | `tsp-status-report` | 电量、里程、速度等状态变化 |
| **位置信息上报** | TSP GPS推送 | `tsp-location-report` | 车辆位置实时更新 |
| **报警信息上报** | TSP 异常检测 | `tsp-alarm-report` | 车辆异常、故障报警 |
| **车辆事件上报** | TSP 事件触发 | `tsp-event-report` | 开门、关门、启动等事件 |

**实现方式**：
```java
// Vehicle Service 中实现 Kafka 消费者
@Component
public class TspStatusReportConsumer {
    
    @Resource
    private VehicleStatusService vehicleStatusService;
    
    @Resource
    private RedisMQTemplate redisMQTemplate; // 推送给客户端
    
    @KafkaListener(topics = "tsp-status-report")
    public void handleStatusReport(TspStatusReportMessage message) {
        // 1. 更新本地数据库
        vehicleStatusService.updateStatus(message.getVehicleId(), message);
        
        // 2. 推送给客户端（通过 Redis MQ → Message Service → WebSocket）
        VehicleStatusMessage pushMessage = convert(message);
        redisMQTemplate.send("vehicle-status-push", pushMessage);
        
        log.info("车辆状态已更新并推送: vehicleId={}", message.getVehicleId());
    }
}
```

**链路图**：
```
TSP平台 → [Kafka Producer] → Kafka Topic: tsp-status-report
                                    ↓
                            Vehicle Service (Kafka Consumer)
                                    ↓
                            更新本地数据库
                                    ↓
                            Redis MQ → Message Service
                                    ↓
                            WebSocket → 客户端（实时推送）
```

---

#### 4.2.2 批量数据上报（必须异步）

| 场景 | 触发方式 | Kafka Topic | 说明 |
|------|---------|------------|------|
| **历史轨迹上报** | TSP 批量推送 | `tsp-track-report` | 车辆历史行驶轨迹 |
| **统计数据上报** | TSP 定时汇总 | `tsp-statistics-report` | 日/周/月统计数据 |
| **诊断数据上报** | TSP 诊断完成 | `tsp-diagnosis-report` | 车辆诊断报告 |

**说明**：这些数据量大，处理时间长，必须异步处理。

---

#### 4.2.3 长时间控制任务（可选异步）

| 场景 | 接口路径 | 调用链路 | 说明 |
|------|---------|---------|------|
| **OTA升级** | `/app/vehicle/ota/upgrade` | 路径一 | 固件升级，可能需要10-30分钟 |
| **远程诊断** | `/app/vehicle/diagnosis` | 路径一 | 车辆诊断，可能需要5-10分钟 |

**实现方式**：
```java
@Service
public class VehicleOtaServiceImpl {
    
    public CommonResult<String> startOtaUpgrade(VehicleOtaReqDTO reqDTO) {
        // 1. 发送升级请求到 TSP（异步，不等待）
        String taskId = UUID.randomUUID().toString();
        kafkaTemplate.send("tsp-ota-request", new TspOtaRequestMessage(taskId, reqDTO));
        
        // 2. 立即返回任务ID
        return success(taskId);
    }
    
    // TSP 通过 Kafka 回调升级结果
    @KafkaListener(topics = "tsp-ota-result")
    public void handleOtaResult(TspOtaResultMessage message) {
        // 更新升级状态
        updateOtaStatus(message.getTaskId(), message);
        
        // 推送结果到客户端
        pushOtaResultToClient(message);
    }
}
```

**链路图**：
```
客户端 → Gateway → Business Service → Vehicle Service → [Kafka发送] → TSP平台
                                                              ↓
                                                        立即返回任务ID
                                                              ↓
客户端 ← Gateway ← Business Service ← Vehicle Service ← [返回taskId]

（后续）
TSP平台处理完成 → [Kafka回调] → Vehicle Service → 推送结果到客户端
```

---

### 4.3 异步场景总结

| 场景类型 | 数量 | 特点 | Kafka Topic |
|---------|------|------|------------|
| 状态上报 | 4个 | TSP主动推送，高并发 | `tsp-status-report` 等 |
| 批量数据 | 3个 | 数据量大，处理时间长 | `tsp-track-report` 等 |
| 长时间任务 | 2个 | 处理时间>5分钟 | `tsp-ota-result` 等 |
| **总计** | **9个** | - | - |

---

## 五、直接调用 Vehicle Service 的场景（不走 Business Service）

### 5.1 场景特征
- **纯车辆操作**：不涉及业务逻辑
- **性能要求高**：减少调用链路，降低延迟
- **无业务聚合**：不需要聚合其他服务数据

### 5.2 具体场景列表

#### 5.2.1 车辆状态实时查询（直接调用）

| 场景 | 接口路径 | 调用链路 | 说明 |
|------|---------|---------|------|
| **查询车辆状态** | `/app-api/vehicle/status` | 路径二 | 直接查询，无需业务逻辑 |
| **查询车辆位置** | `/app-api/vehicle/location` | 路径二 | 直接查询GPS位置 |

**Gateway 路由配置**：
```yaml
spring:
  cloud:
    gateway:
      routes:
        # 车辆状态查询直接走 Vehicle Service
        - id: vehicle-status-direct
          uri: lb://xdz-vehicle
          predicates:
            - Path=/app-api/vehicle/status,/app-api/vehicle/location
          filters:
            - StripPrefix=1
```

**链路图**：
```
客户端 → Gateway → Vehicle Service → TSP平台
                      ↓
                  直接返回
                      ↓
客户端 ← Gateway ← Vehicle Service
```

---

#### 5.2.2 车辆控制快速操作（直接调用）

| 场景 | 接口路径 | 调用链路 | 说明 |
|------|---------|---------|------|
| **快速开锁** | `/app-api/vehicle/control/unlock` | 路径二 | 紧急情况，需要最快响应 |
| **快速关锁** | `/app-api/vehicle/control/lock` | 路径二 | 紧急情况，需要最快响应 |

**说明**：这些是紧急操作，需要最快响应，不走 Business Service 可以减少延迟。

---

#### 5.2.3 TSP 回调接口（直接调用）

| 场景 | 接口路径 | 调用链路 | 说明 |
|------|---------|---------|------|
| **TSP HTTP回调** | `/tsp/callback/**` | 路径二 | TSP 直接回调 Vehicle Service |
| **TSP Webhook** | `/tsp/webhook/**` | 路径二 | TSP 事件推送 |

**说明**：TSP 的回调接口应该直接暴露在 Vehicle Service，不需要经过 Business Service。

**实现方式**：
```java
@RestController
@RequestMapping("/tsp")
public class TspCallbackController {
    
    @PostMapping("/callback/status")
    public CommonResult<Boolean> handleStatusCallback(@RequestBody TspStatusCallback callback) {
        // 直接处理 TSP 回调，更新状态
        vehicleStatusService.updateFromTsp(callback);
        return success(true);
    }
}
```

---

### 5.3 直接调用场景总结

| 场景类型 | 数量 | 特点 | 路由前缀 |
|---------|------|------|---------|
| 状态查询 | 2个 | 实时查询，性能要求高 | `/app-api/vehicle/status` |
| 快速控制 | 2个 | 紧急操作，延迟要求低 | `/app-api/vehicle/control` |
| TSP回调 | 2个 | 外部系统回调 | `/tsp/callback` |
| **总计** | **6个** | - | - |

---

## 六、完整场景分类表

### 6.1 同步场景（11个）

| 序号 | 场景 | 接口路径 | 调用链路 | TSP接口 | 超时时间 |
|------|------|---------|---------|---------|---------|
| 1 | 开锁 | `/app/vehicle/control/unlock` | 路径一 | `UNLOCK` | 5秒 |
| 2 | 关锁 | `/app/vehicle/control/lock` | 路径一 | `LOCK` | 5秒 |
| 3 | 启动 | `/app/vehicle/control/start` | 路径一 | `START` | 5秒 |
| 4 | 熄火 | `/app/vehicle/control/stop` | 路径一 | `STOP` | 5秒 |
| 5 | 鸣笛 | `/app/vehicle/control/horn` | 路径一 | `HORN` | 5秒 |
| 6 | 灯光 | `/app/vehicle/control/light` | 路径一 | `LIGHT` | 5秒 |
| 7 | 查询状态 | `/app/vehicle/status` | 路径一 | `GET_STATUS` | 3秒 |
| 8 | 查询位置 | `/app/vehicle/location` | 路径一 | `GET_LOCATION` | 3秒 |
| 9 | 查询信息 | `/app/vehicle/get` | 路径一 | `GET_VEHICLE_INFO` | 3秒 |
| 10 | 绑定车辆 | `/app/vehicle/bind` | 路径一 | `BIND_VEHICLE` | 5秒 |
| 11 | 解绑车辆 | `/app/vehicle/unbind` | 路径一 | `UNBIND_VEHICLE` | 5秒 |

### 6.2 异步场景（9个）

| 序号 | 场景 | 触发方式 | Kafka Topic | 说明 |
|------|------|---------|------------|------|
| 1 | 状态上报 | TSP推送 | `tsp-status-report` | 电量、里程、速度 |
| 2 | 位置上报 | TSP推送 | `tsp-location-report` | GPS位置更新 |
| 3 | 报警上报 | TSP推送 | `tsp-alarm-report` | 车辆异常报警 |
| 4 | 事件上报 | TSP推送 | `tsp-event-report` | 开门、关门等事件 |
| 5 | 轨迹上报 | TSP批量 | `tsp-track-report` | 历史行驶轨迹 |
| 6 | 统计上报 | TSP定时 | `tsp-statistics-report` | 日/周/月统计 |
| 7 | 诊断上报 | TSP完成 | `tsp-diagnosis-report` | 诊断报告 |
| 8 | OTA升级 | 客户端触发 | `tsp-ota-result` | 固件升级结果 |
| 9 | 远程诊断 | 客户端触发 | `tsp-diagnosis-result` | 诊断结果 |

### 6.3 直接调用场景（6个）

| 序号 | 场景 | 接口路径 | 调用链路 | 说明 |
|------|------|---------|---------|------|
| 1 | 快速状态查询 | `/app-api/vehicle/status` | 路径二 | 直接查询，不走业务服务 |
| 2 | 快速位置查询 | `/app-api/vehicle/location` | 路径二 | 直接查询，不走业务服务 |
| 3 | 快速开锁 | `/app-api/vehicle/control/unlock` | 路径二 | 紧急操作，最快响应 |
| 4 | 快速关锁 | `/app-api/vehicle/control/lock` | 路径二 | 紧急操作，最快响应 |
| 5 | TSP HTTP回调 | `/tsp/callback/**` | 路径二 | TSP直接回调 |
| 6 | TSP Webhook | `/tsp/webhook/**` | 路径二 | TSP事件推送 |

---

## 七、技术实现建议

### 7.1 同步调用实现

**使用 Feign 客户端**：
```java
@FeignClient(name = "tsp-platform", url = "${tsp.url}")
public interface TspApiClient {
    
    @PostMapping("/api/v1/vehicle/control")
    TspControlResponse sendControlCommand(@RequestBody TspControlRequest request);
    
    @GetMapping("/api/v1/vehicle/{vehicleId}/status")
    TspStatusResponse getRealTimeStatus(@PathVariable("vehicleId") Long vehicleId);
}
```

**配置超时时间**：
```yaml
feign:
  client:
    config:
      tsp-platform:
        connectTimeout: 3000
        readTimeout: 5000
```

### 7.2 异步调用实现

**Kafka 配置**：
```yaml
spring:
  kafka:
    bootstrap-servers: ${kafka.servers}
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      group-id: vehicle-service-group
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
```

**消费者实现**：
```java
@Component
@Slf4j
public class TspMessageConsumer {
    
    @KafkaListener(topics = "tsp-status-report")
    public void consumeStatusReport(TspStatusReportMessage message) {
        // 处理消息
    }
}
```

### 7.3 Gateway 路由配置

```yaml
spring:
  cloud:
    gateway:
      routes:
        # 直接调用 Vehicle Service 的路由
        - id: vehicle-direct
          uri: lb://xdz-vehicle
          predicates:
            - Path=/app-api/vehicle/**,/tsp/**
          filters:
            - StripPrefix=0
        
        # 通过 Business Service 的路由
        - id: vehicle-via-business
          uri: lb://xdz-business
          predicates:
            - Path=/app/vehicle/**
          filters:
            - StripPrefix=0
```

---

## 八、总结

### 8.1 场景统计

| 类型 | 数量 | 占比 |
|------|------|------|
| 同步场景 | 11个 | 42% |
| 异步场景 | 9个 | 35% |
| 直接调用 | 6个 | 23% |
| **总计** | **26个** | **100%** |

### 8.2 选择原则

1. **同步场景**：用户操作、实时查询、需要立即反馈
2. **异步场景**：TSP主动推送、批量数据、长时间任务
3. **直接调用**：纯车辆操作、性能要求高、无业务逻辑

### 8.3 注意事项

1. **超时处理**：同步调用必须设置合理的超时时间
2. **重试机制**：异步消息需要支持重试和幂等性
3. **监控告警**：所有 TSP 调用都需要监控和告警
4. **降级策略**：TSP 不可用时，需要有降级方案

---

## 九、附录

### 9.1 相关接口文档
- TSP 平台 API 文档：`docs/tsp-api.md`
- Kafka Topic 设计：`docs/kafka-topics.md`
- Gateway 路由配置：`docs/gateway-routes.md`

### 9.2 联系方式
- 技术负责人：xxx
- TSP 对接人：xxx
- 文档维护：Vehicle Service 团队

---

**文档版本**：v1.0  
**最后更新**：2025-01-XX  
**维护人**：Vehicle Service Team













