feat: 补齐开放平台车辆实况与统计时间字段
This commit is contained in:
@@ -196,7 +196,8 @@ func (r *MySQLRepository) RealtimeVehicles(ctx context.Context, vins []string, n
|
||||
query := `
|
||||
SELECT l.vin,l.protocol,COALESCE(l.longitude,0),COALESCE(l.latitude,0),
|
||||
COALESCE(l.speed_kmh,0),l.soc_percent,COALESCE(l.total_mileage_km,0),l.updated_at,
|
||||
MAX(CASE WHEN l.updated_at>=? THEN 1 ELSE 0 END) OVER (PARTITION BY l.vin) AS active_today
|
||||
MAX(CASE WHEN l.updated_at>=? THEN 1 ELSE 0 END) OVER (PARTITION BY l.vin) AS active_today,
|
||||
l.event_time,l.received_at,l.event_id
|
||||
FROM vehicle_realtime_location l
|
||||
WHERE BINARY l.vin IN (` + placeholders + `)
|
||||
ORDER BY l.vin,
|
||||
@@ -212,9 +213,12 @@ ORDER BY l.vin,
|
||||
for rows.Next() {
|
||||
var point RealtimeVehiclePoint
|
||||
var soc sql.NullFloat64
|
||||
if err := rows.Scan(&point.VIN, &point.Protocol, &point.Longitude, &point.Latitude, &point.SpeedKmh, &soc, &point.TotalMileageKm, &point.ObservedAt, &point.ActiveToday); err != nil {
|
||||
var locationAt, receivedAt sql.NullTime
|
||||
var eventID sql.NullString
|
||||
if err := rows.Scan(&point.VIN, &point.Protocol, &point.Longitude, &point.Latitude, &point.SpeedKmh, &soc, &point.TotalMileageKm, &point.ObservedAt, &point.ActiveToday, &locationAt, &receivedAt, &eventID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
point.LocationObservedAt, point.LocationReceivedAt, point.LocationEventID = locationAt.Time, receivedAt.Time, eventID.String
|
||||
if soc.Valid && soc.Float64 >= 0 && soc.Float64 <= 100 {
|
||||
value := round3(soc.Float64)
|
||||
point.SOCPercent = &value
|
||||
@@ -229,7 +233,16 @@ ORDER BY l.vin,
|
||||
out[point.VIN] = selected
|
||||
}
|
||||
}
|
||||
return out, rows.Err()
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.enrichRealtimeLiveData(ctx, vins, out, now); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (r *MySQLRepository) HydrogenStations(ctx context.Context, request HydrogenStationRequest) ([]HydrogenStation, error) {
|
||||
@@ -313,7 +326,8 @@ func (r *MySQLRepository) DailyHydrogen(ctx context.Context, vins []string, date
|
||||
}
|
||||
query, args := inQuery(`
|
||||
SELECT vin,DATE_FORMAT(stat_date,'%Y-%m-%d'),consumption_kg,sample_count,quality_status,quality_reason,
|
||||
calculation_phase,algorithm_version
|
||||
calculation_phase,algorithm_version,COALESCE(evidence_json,'null'),
|
||||
DATE_FORMAT(updated_at,'%Y-%m-%dT%H:%i:%s.%f+08:00')
|
||||
FROM vehicle_open_daily_energy
|
||||
WHERE energy_type='HYDROGEN' AND stat_date=? AND vin IN (%s)`, date, vins)
|
||||
rows, err := r.db.QueryContext(ctx, query, args...)
|
||||
@@ -324,7 +338,7 @@ WHERE energy_type='HYDROGEN' AND stat_date=? AND vin IN (%s)`, date, vins)
|
||||
out := make(map[string]DailyHydrogen, len(vins))
|
||||
for rows.Next() {
|
||||
var value DailyHydrogen
|
||||
if err := rows.Scan(&value.VIN, &value.Date, &value.ConsumptionKg, &value.SampleCount, &value.QualityStatus, &value.QualityReason, &value.CalculationPhase, &value.AlgorithmVersion); err != nil {
|
||||
if err := rows.Scan(&value.VIN, &value.Date, &value.ConsumptionKg, &value.SampleCount, &value.QualityStatus, &value.QualityReason, &value.CalculationPhase, &value.AlgorithmVersion, &value.EvidenceJSON, &value.UpdatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[value.VIN] = value
|
||||
@@ -407,7 +421,12 @@ SELECT
|
||||
AND selected.is_selected=1
|
||||
AND selected.latest_event_time IS NOT NULL
|
||||
),'%Y-%m-%dT%H:%i:%s+08:00'),''),
|
||||
DATE_FORMAT(m.updated_at,'%Y-%m-%dT%H:%i:%s+08:00')
|
||||
DATE_FORMAT(m.updated_at,'%Y-%m-%dT%H:%i:%s+08:00'),
|
||||
COALESCE(DATE_FORMAT((SELECT MIN(selected.first_event_time)
|
||||
FROM vehicle_daily_mileage_source selected
|
||||
WHERE selected.vin=m.vin AND selected.stat_date=m.stat_date
|
||||
AND selected.protocol=m.protocol AND selected.is_selected=1
|
||||
),'%Y-%m-%dT%H:%i:%s+08:00'),'')
|
||||
FROM vehicle_daily_mileage m
|
||||
WHERE m.stat_date BETWEEN ? AND ?
|
||||
AND m.vin IN (` + placeholders + `)
|
||||
@@ -445,7 +464,7 @@ ORDER BY m.stat_date,m.vin,
|
||||
out := make(map[string]DailyMileage, len(vins))
|
||||
for rows.Next() {
|
||||
var value DailyMileage
|
||||
if err := rows.Scan(&value.VIN, &value.Date, &value.Protocol, &value.MileageKm, &value.TotalMileageKm, &value.DataTime, &value.UpdatedAt); err != nil {
|
||||
if err := rows.Scan(&value.VIN, &value.Date, &value.Protocol, &value.MileageKm, &value.TotalMileageKm, &value.DataTime, &value.UpdatedAt, &value.StatisticsStartTime); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := dailyMileageKey(value.VIN, value.Date)
|
||||
@@ -805,7 +824,8 @@ func inQuery(template, first string, values []string) (string, []any) {
|
||||
for _, value := range values {
|
||||
args = append(args, value)
|
||||
}
|
||||
return strings.Replace(template, "%s", placeholders, 1), args
|
||||
// Match the IN marker, not MySQL DATE_FORMAT seconds (%s).
|
||||
return strings.Replace(template, "IN (%s)", "IN ("+placeholders+")", 1), args
|
||||
}
|
||||
|
||||
func nullableTime(value *time.Time) any {
|
||||
|
||||
Reference in New Issue
Block a user