fix(access): report only real vehicle sources

This commit is contained in:
lingniu
2026-07-16 18:07:45 +08:00
parent 85de053962
commit ff6df370cb
10 changed files with 106 additions and 54 deletions

View File

@@ -223,11 +223,12 @@ func buildAccessVehicleGroup(items []AccessEvidenceRow, config AccessThresholdCo
OEM: strings.TrimSpace(base.OEM),
Model: strings.TrimSpace(base.Model),
Company: strings.TrimSpace(base.Company),
ExpectedProtocols: append([]string(nil), canonicalVehicleProtocols...),
ExpectedProtocols: []string{},
ActualProtocols: []string{},
MissingProtocols: []string{},
ProtocolStatuses: []AccessProtocolStatus{},
ExpectationEvidence: "平台标准接入基线GB32960 / JT808 / YUTONG_MQTT",
MasterDataIssues: []string{},
ExpectationEvidence: "尚未接入业务系统的应接协议口径;当前只展示真实接入来源,不推断车辆必须具备三协议",
ConnectionState: "not_connected",
OnlineState: "never_reported",
FirstSeenEvidence: "尚未形成任何协议接入快照",
@@ -254,29 +255,29 @@ func buildAccessVehicleGroup(items []AccessEvidenceRow, config AccessThresholdCo
}
onlineCount := 0
unknownCount := 0
connectedCount := 0
for _, protocol := range canonicalVehicleProtocols {
item, connected := byProtocol[protocol]
if !connected {
threshold := accessProtocolThreshold(config, protocol)
row.MissingProtocols = append(row.MissingProtocols, protocol)
row.ProtocolStatuses = append(row.ProtocolStatuses, AccessProtocolStatus{
Protocol: protocol, Expected: true, Connected: false, OnlineState: "never_reported", ThresholdSec: threshold,
FirstSeenEvidence: "应接协议尚未形成实时快照", ReportIntervalEvidence: "尚无接收样本",
Protocol: protocol, Expected: false, Connected: false, OnlineState: "never_reported", ThresholdSec: threshold,
FirstSeenEvidence: "当前未发现该协议来源;在业务应接口径接入前不判定为缺失", ReportIntervalEvidence: "尚无接收样本",
})
continue
}
source := buildAccessVehicleRow(item, config, now)
connectedCount++
row.ActualProtocols = append(row.ActualProtocols, protocol)
if source.OnlineState == "online" {
onlineCount++
}
if source.OnlineState == "unknown" {
unknownCount++
}
if source.DelayAbnormal {
row.DelayAbnormal = true
}
row.ProtocolStatuses = append(row.ProtocolStatuses, AccessProtocolStatus{
Protocol: protocol, Expected: true, Connected: true, Provider: source.Provider,
Protocol: protocol, Expected: false, Connected: true, Provider: source.Provider,
FirstSeenAt: source.FirstSeenAt, LatestEventAt: source.LatestEventAt, LatestReceivedAt: source.LatestReceivedAt,
ReportIntervalSec: source.ReportIntervalSec, DataDelaySec: source.DataDelaySec, FreshnessSec: source.FreshnessSec,
OnlineState: source.OnlineState, ThresholdSec: source.ThresholdSec, DelayAbnormal: source.DelayAbnormal,
@@ -292,10 +293,16 @@ func buildAccessVehicleGroup(items []AccessEvidenceRow, config AccessThresholdCo
copyAccessPrimaryFields(&row, source)
}
}
for protocol, item := range byProtocol {
extraProtocols := make([]string, 0)
for protocol := range byProtocol {
if containsString(canonicalVehicleProtocols, protocol) {
continue
}
extraProtocols = append(extraProtocols, protocol)
}
sort.Strings(extraProtocols)
for _, protocol := range extraProtocols {
item := byProtocol[protocol]
source := buildAccessVehicleRow(item, config, now)
row.ActualProtocols = append(row.ActualProtocols, protocol)
if source.OnlineState == "online" {
@@ -316,29 +323,47 @@ func buildAccessVehicleGroup(items []AccessEvidenceRow, config AccessThresholdCo
copyAccessPrimaryFields(&row, source)
}
}
if accessMasterDataMissing(row.OEM) {
row.MasterDataIssues = append(row.MasterDataIssues, "车辆品牌未维护")
}
for _, status := range row.ProtocolStatuses {
if status.Connected && accessMasterDataMissing(status.Provider) {
row.MasterDataIssues = append(row.MasterDataIssues, status.Protocol+" 接入方未维护")
}
}
sourceCount := len(row.ActualProtocols)
switch {
case connectedCount == 0 && len(row.ActualProtocols) == 0:
case sourceCount == 0:
row.ConnectionState = "not_connected"
row.OnlineState = "never_reported"
case connectedCount == len(canonicalVehicleProtocols) && onlineCount == connectedCount:
row.ConnectionState = "healthy"
row.OnlineState = "online"
case onlineCount == 0 && unknownCount > 0:
row.ConnectionState = "incomplete"
case onlineCount == 0 && unknownCount == sourceCount:
row.ConnectionState = "degraded"
row.OnlineState = "unknown"
case onlineCount == 0:
row.ConnectionState = "offline"
row.OnlineState = "offline"
case connectedCount < len(canonicalVehicleProtocols):
case onlineCount < sourceCount || row.DelayAbnormal:
row.ConnectionState = "degraded"
row.OnlineState = "online"
case len(row.MasterDataIssues) > 0:
row.ConnectionState = "incomplete"
row.OnlineState = "online"
default:
row.ConnectionState = "degraded"
row.ConnectionState = "healthy"
row.OnlineState = "online"
}
return row
}
func accessMasterDataMissing(value string) bool {
switch strings.ToLower(strings.TrimSpace(value)) {
case "", "未维护", "待维护", "unknown", "未知":
return true
default:
return false
}
}
func accessProtocolThreshold(config AccessThresholdConfig, protocol string) int {
for _, override := range config.Protocols {
if strings.EqualFold(override.Protocol, protocol) {
@@ -446,8 +471,14 @@ func keepAccessRow(row AccessVehicleRow, query AccessQuery) bool {
if value := strings.TrimSpace(query.Protocol); value != "" && !containsString(row.ActualProtocols, value) {
return false
}
if value := strings.TrimSpace(query.OEM); value != "" && !strings.EqualFold(value, row.OEM) {
return false
if value := strings.TrimSpace(query.OEM); value != "" {
if value == "未维护" {
if !accessMasterDataMissing(row.OEM) {
return false
}
} else if !strings.EqualFold(value, row.OEM) {
return false
}
}
if value := strings.ToLower(strings.TrimSpace(query.Model)); value != "" && !strings.Contains(strings.ToLower(row.Model), value) {
return false