fix(mileage): recover sparse source daily distance
This commit is contained in:
@@ -99,13 +99,20 @@ func CalculateGPSMileageSegment(previous, current GPSMileagePoint) GPSMileageSeg
|
||||
}
|
||||
|
||||
func GPSMileagePointFromEnvelope(env envelope.FrameEnvelope, identity SourceIdentity, loc *time.Location) (GPSMileagePoint, bool) {
|
||||
if env.Protocol != envelope.ProtocolJT808 || strings.TrimSpace(env.VIN) == "" {
|
||||
if !supportsGPSMileageFallback(env.Protocol) || strings.TrimSpace(env.VIN) == "" {
|
||||
return GPSMileagePoint{}, false
|
||||
}
|
||||
location, ok := telemetry.LocationProjectionForProtocol(env.Protocol, env.Fields)
|
||||
if !ok || !validGPSCoordinate(location.Longitude, location.Latitude) {
|
||||
return GPSMileagePoint{}, false
|
||||
}
|
||||
// JT808 terminals often omit speed together with odometer data, so keep the
|
||||
// established coordinate-only fallback. GB32960 and Yutong report much more
|
||||
// frequently; require positive device speed to prevent stationary GPS jitter
|
||||
// from becoming mileage and to keep the MySQL state path inexpensive.
|
||||
if env.Protocol != envelope.ProtocolJT808 && (location.SpeedKMH == nil || *location.SpeedKMH <= 0) {
|
||||
return GPSMileagePoint{}, false
|
||||
}
|
||||
eventMS, _, ok := envelope.NormalizedEventTimeMSWithReason(env)
|
||||
if !ok {
|
||||
return GPSMileagePoint{}, false
|
||||
@@ -131,7 +138,16 @@ func GPSMileagePointFromEnvelope(env envelope.FrameEnvelope, identity SourceIden
|
||||
}, true
|
||||
}
|
||||
|
||||
func AccumulateJT808GPSMileage(ctx context.Context, exec Execer, point GPSMileagePoint) (GPSMileageState, bool, error) {
|
||||
func supportsGPSMileageFallback(protocol envelope.Protocol) bool {
|
||||
switch protocol {
|
||||
case envelope.ProtocolGB32960, envelope.ProtocolJT808, envelope.ProtocolYutongMQTT:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func AccumulateGPSMileage(ctx context.Context, exec Execer, point GPSMileagePoint) (GPSMileageState, bool, error) {
|
||||
beginner, ok := exec.(txBeginner)
|
||||
if !ok || strings.TrimSpace(point.VIN) == "" || strings.TrimSpace(point.SourceKey) == "" || point.EventTime.IsZero() {
|
||||
return GPSMileageState{}, false, nil
|
||||
@@ -242,6 +258,12 @@ func AccumulateJT808GPSMileage(ctx context.Context, exec Execer, point GPSMileag
|
||||
return state, true, nil
|
||||
}
|
||||
|
||||
// AccumulateJT808GPSMileage remains as a compatibility wrapper for callers and
|
||||
// operational tooling compiled against the original JT808-only fallback.
|
||||
func AccumulateJT808GPSMileage(ctx context.Context, exec Execer, point GPSMileagePoint) (GPSMileageState, bool, error) {
|
||||
return AccumulateGPSMileage(ctx, exec, point)
|
||||
}
|
||||
|
||||
func selectExistingGPSMileageBaseline(ctx context.Context, tx *sql.Tx, point GPSMileagePoint) (float64, time.Time, int64, int64, error) {
|
||||
var mileage sql.NullFloat64
|
||||
var firstEvent sql.NullTime
|
||||
@@ -293,7 +315,7 @@ func upsertGPSMileageCandidate(ctx context.Context, exec Execer, point GPSMileag
|
||||
point.SourceEndpoint,
|
||||
point.Phone,
|
||||
point.DeviceID,
|
||||
"JT808 GPS轨迹估算",
|
||||
gpsMileagePlatformName(point.Protocol),
|
||||
0,
|
||||
state.DailyMileageKM,
|
||||
state.DailyMileageKM,
|
||||
@@ -306,6 +328,17 @@ func upsertGPSMileageCandidate(ctx context.Context, exec Execer, point GPSMileag
|
||||
return err
|
||||
}
|
||||
|
||||
func gpsMileagePlatformName(protocol envelope.Protocol) string {
|
||||
switch protocol {
|
||||
case envelope.ProtocolGB32960:
|
||||
return "GB32960 GPS轨迹估算"
|
||||
case envelope.ProtocolYutongMQTT:
|
||||
return "宇通 GPS轨迹估算"
|
||||
default:
|
||||
return "JT808 GPS轨迹估算"
|
||||
}
|
||||
}
|
||||
|
||||
func gpsMileageCandidateSourceKey(point GPSMileagePoint) string {
|
||||
identity := strings.TrimSpace(point.Phone)
|
||||
if identity == "" {
|
||||
|
||||
Reference in New Issue
Block a user