Compare commits
2 Commits
eb48d16181
...
e7c8c57296
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7c8c57296 | ||
|
|
6b55694c43 |
@@ -174,3 +174,69 @@ gd_fc_vehicle_hydrogen_mass_kg=4.3
|
|||||||
|
|
||||||
- JT808 真实 phone `14894135060` 到 VIN 的绑定数据维护与统计复验。
|
- JT808 真实 phone `14894135060` 到 VIN 的绑定数据维护与统计复验。
|
||||||
- Go 旁路尚未切换到生产 `32960/808` 端口;仍运行在 `23296/18080`。
|
- Go 旁路尚未切换到生产 `32960/808` 端口;仍运行在 `23296/18080`。
|
||||||
|
|
||||||
|
## 2026-07-01 22:43 JT808 前导零 phone 身份解析复验
|
||||||
|
|
||||||
|
部署版本已更新:
|
||||||
|
|
||||||
|
- Git commit:`6b55694`
|
||||||
|
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-6b55694-20260701224300`
|
||||||
|
|
||||||
|
本轮修复内容:
|
||||||
|
|
||||||
|
- JT808 2011 老版包头的终端手机号按 BCD[6] 解析会保留前导 `0`,例如包头为 `013079963379`。
|
||||||
|
- `vehicle_identity_binding.phone` 中实际维护的是去前导零后的手机号 `13079963379`。
|
||||||
|
- 身份解析候选键已调整为先查原始 phone,再查去前导零 phone,之后再按 `device_id`、`plate` 降级。
|
||||||
|
|
||||||
|
真实帧复验样本:
|
||||||
|
|
||||||
|
- 归档帧:`/opt/lingniu/vehicle-ingest/gb32960/archive/2026/07/01/JT808/unknown/1782903942845000.bin`
|
||||||
|
- 消息:`0x0200` 位置信息汇报
|
||||||
|
- 包头 phone:`013079963379`
|
||||||
|
- 绑定表 phone:`13079963379`
|
||||||
|
- 解析 VIN:`LKLG7C4E3NA774736`
|
||||||
|
|
||||||
|
Kafka `vehicle.raw.go.jt808.v1` 最新消息确认:
|
||||||
|
|
||||||
|
```text
|
||||||
|
vin=LKLG7C4E3NA774736
|
||||||
|
phone=013079963379
|
||||||
|
parsed.header.phone_trim_zero=13079963379
|
||||||
|
parsed.identity.resolved=true
|
||||||
|
parsed.identity.source=phone
|
||||||
|
parsed.identity.value=13079963379
|
||||||
|
```
|
||||||
|
|
||||||
|
Realtime API 确认:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/realtime/vehicles/LKLG7C4E3NA774736
|
||||||
|
|
||||||
|
longitude=119.557997
|
||||||
|
latitude=29.049092
|
||||||
|
speed_kmh=0
|
||||||
|
total_mileage_km=0
|
||||||
|
device_time=2026-07-01T19:05:40+08:00
|
||||||
|
```
|
||||||
|
|
||||||
|
TDengine 确认:
|
||||||
|
|
||||||
|
```text
|
||||||
|
raw_frames:
|
||||||
|
2026-07-01 14:49:10.913 | JT808 | LKLG7C4E3NA774736 | phone=013079963379 | message_id=512
|
||||||
|
|
||||||
|
vehicle_locations:
|
||||||
|
2026-07-01 11:05:40.000 | JT808 | LKLG7C4E3NA774736 | lon=119.557997 | lat=29.049092 | speed=0 | mileage=0
|
||||||
|
|
||||||
|
vehicle_mileage_points:
|
||||||
|
2026-07-01 11:05:40.000 | JT808 | LKLG7C4E3NA774736 | mileage=0
|
||||||
|
```
|
||||||
|
|
||||||
|
MySQL `vehicle_daily_metric` 确认:
|
||||||
|
|
||||||
|
```text
|
||||||
|
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_mileage_km | 0.000 | sample_count=1 | TOTAL_MILEAGE_DIFF
|
||||||
|
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_total_mileage_km | 0.000 | sample_count=1 | TOTAL_MILEAGE_DIFF
|
||||||
|
```
|
||||||
|
|
||||||
|
说明:该真实位置帧携带的表 27 附加项 `0x01` 总里程值为 `0`,因此本次只验证身份解析、链路落地和差值统计写入;要验证非零日里程,需要回放或等待同一 VIN 的非零总里程连续位置点。
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ func CandidateKeys(env envelope.FrameEnvelope) []CandidateKey {
|
|||||||
out = append(out, CandidateKey{Column: column, Value: value})
|
out = append(out, CandidateKey{Column: column, Value: value})
|
||||||
}
|
}
|
||||||
add("phone", env.Phone)
|
add("phone", env.Phone)
|
||||||
|
if trimmed := strings.TrimLeft(strings.TrimSpace(env.Phone), "0"); trimmed != "" {
|
||||||
|
add("phone", trimmed)
|
||||||
|
}
|
||||||
add("device_id", env.DeviceID)
|
add("device_id", env.DeviceID)
|
||||||
add("plate", env.Plate)
|
add("plate", env.Plate)
|
||||||
add("vin", env.VehicleKeyHint)
|
add("vin", env.VehicleKeyHint)
|
||||||
|
|||||||
@@ -21,7 +21,26 @@ func TestCandidateKeysPrioritizesPhoneDevicePlate(t *testing.T) {
|
|||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
got = append(got, key.Column+"="+key.Value)
|
got = append(got, key.Column+"="+key.Value)
|
||||||
}
|
}
|
||||||
want := []string{"phone=013307795425", "device_id=D1", "plate=豫A12345", "vin=D1"}
|
want := []string{"phone=013307795425", "phone=13307795425", "device_id=D1", "plate=豫A12345", "vin=D1"}
|
||||||
|
if len(got) != len(want) {
|
||||||
|
t.Fatalf("candidate count = %d got=%#v", len(got), got)
|
||||||
|
}
|
||||||
|
for i := range want {
|
||||||
|
if got[i] != want[i] {
|
||||||
|
t.Fatalf("candidate[%d] = %q, want %q", i, got[i], want[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCandidateKeysAddsTrimmedPhoneVariant(t *testing.T) {
|
||||||
|
keys := CandidateKeys(envelope.FrameEnvelope{
|
||||||
|
Phone: "013079963379",
|
||||||
|
})
|
||||||
|
got := []string{}
|
||||||
|
for _, key := range keys {
|
||||||
|
got = append(got, key.Column+"="+key.Value)
|
||||||
|
}
|
||||||
|
want := []string{"phone=013079963379", "phone=13079963379"}
|
||||||
if len(got) != len(want) {
|
if len(got) != len(want) {
|
||||||
t.Fatalf("candidate count = %d got=%#v", len(got), got)
|
t.Fatalf("candidate count = %d got=%#v", len(got), got)
|
||||||
}
|
}
|
||||||
@@ -66,6 +85,9 @@ func TestMySQLResolverFallsBackToDeviceID(t *testing.T) {
|
|||||||
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
||||||
WithArgs("013307795425").
|
WithArgs("013307795425").
|
||||||
WillReturnError(sql.ErrNoRows)
|
WillReturnError(sql.ErrNoRows)
|
||||||
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
||||||
|
WithArgs("13307795425").
|
||||||
|
WillReturnError(sql.ErrNoRows)
|
||||||
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE device_id = \\?").
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE device_id = \\?").
|
||||||
WithArgs("D1").
|
WithArgs("D1").
|
||||||
WillReturnRows(sqlmock.NewRows([]string{"vin"}).AddRow("LNBVIN00000000002"))
|
WillReturnRows(sqlmock.NewRows([]string{"vin"}).AddRow("LNBVIN00000000002"))
|
||||||
|
|||||||
Reference in New Issue
Block a user