feat: 补齐开放平台车辆实况与统计时间字段

This commit is contained in:
lingniu
2026-09-08 21:47:58 +08:00
parent 9fa3d81777
commit a6e31effc2
14 changed files with 1376 additions and 62 deletions
@@ -284,13 +284,14 @@ func (s *Service) QueryRealtimeVehicles(ctx context.Context, appKey, traceID str
results := make([]RealtimeVehicleResult, 0, len(plates))
for _, plate := range plates {
vehicle := vehicles[plate]
item := RealtimeVehicleResult{VIN: vehicle.VIN, PlateNumber: plate, MotionStatus: "offline", Status: StatusNoData}
item := RealtimeVehicleResult{VIN: vehicle.VIN, PlateNumber: plate, MotionStatus: "offline", Status: StatusNoData, RealtimeHydrogenData: missingRealtimeHydrogen(""), GPSFixStatus: "UNKNOWN", CoordinateSystem: "UNKNOWN"}
if point, ok := points[vehicle.VIN]; ok {
difference := int64(now.Sub(point.ObservedAt.In(s.location)).Seconds())
if difference < 0 {
difference = 0
}
item.Protocol = externalMileageProtocol(point.Protocol)
applyRealtimeLiveData(&item, point, s.location)
item.RecordTime = point.ObservedAt.In(s.location).Format("2006-01-02 15:04:05")
item.TimeDifferenceSeconds = &difference
item.Online = point.Online
@@ -304,7 +305,7 @@ func (s *Service) QueryRealtimeVehicles(ctx context.Context, appKey, traceID str
speed, mileage := round3(point.SpeedKmh), round3(point.TotalMileageKm)
item.SpeedKmh, item.TotalMileageKm = &speed, &mileage
item.SOCPercent = point.SOCPercent
if validCoordinate(point.Longitude, point.Latitude) {
if item.GPSFixStatus != "NO_FIX" && validCoordinate(point.Longitude, point.Latitude) {
longitude, latitude := point.Longitude, point.Latitude
item.Longitude, item.Latitude = &longitude, &latitude
item.LocationAvailable = true
@@ -387,11 +388,13 @@ func (s *Service) QueryHydrogen(ctx context.Context, appKey, traceID string, req
results := make([]HydrogenResult, 0, len(plates))
for _, plate := range plates {
vehicle := vehicles[plate]
item := HydrogenResult{PlateNumber: plate, Date: date, Status: StatusNoData}
item := HydrogenResult{VIN: vehicle.VIN, PlateNumber: plate, Date: date, Status: StatusNoData}
// Sampling sufficiency is decided by the producer and persisted in
// quality_status. Imported refuelling-ledger rows can be authoritative
// with one transaction, while pressure-derived rows require two samples.
if value, ok := values[vehicle.VIN]; ok {
item.StatisticsStartTime, item.StatisticsEndTime = hydrogenStatisticsInterval(value.EvidenceJSON)
item.UpdatedAt = validStatisticsTimestamp(value.UpdatedAt)
item.CalculationPhase = value.CalculationPhase
item.AlgorithmVersion = value.AlgorithmVersion
item.QualityStatus = value.QualityStatus
@@ -711,6 +714,12 @@ func (s *Service) authorize(ctx context.Context, rawKey string, plates []string,
if len(plates) > 0 && len(vehicles) != len(plates) {
return app, nil, ErrForbidden
}
for _, plate := range plates {
vehicle, ok := vehicles[plate]
if !ok || strings.TrimSpace(vehicle.VIN) == "" || (vehicle.Plate != "" && vehicle.Plate != plate) {
return app, nil, ErrForbidden
}
}
return app, vehicles, nil
}
@@ -991,6 +1000,9 @@ func missingMileageRangeInitialVINs(positions []mileageRangePosition, values map
}
func fillMileageResult(item *MileageResult, value DailyMileage, dailyMileage float64) {
if value.Date == item.Date {
item.StatisticsStartTime, item.StatisticsEndTime = validatedStatisticsInterval(value.StatisticsStartTime, value.DataTime)
}
item.DailyMileageKm = &dailyMileage
totalMileage := value.TotalMileageKm
item.TotalMileageKm = &totalMileage