feat(platform): expose quality issue identity

This commit is contained in:
lingniu
2026-07-03 23:28:10 +08:00
parent 54d74178ea
commit c9e94639d1
6 changed files with 26 additions and 18 deletions

View File

@@ -114,7 +114,7 @@ func TestHandlerHistoryMileageQualityOps(t *testing.T) {
{"/api/mileage/summary?limit=10", "totalMileageKm"},
{"/api/mileage/daily?limit=10", "dailyMileageKm"},
{"/api/quality/summary?limit=10", "issueVehicleCount"},
{"/api/quality/issues?limit=10", "issueType"},
{"/api/quality/issues?limit=10", "sourceEndpoint"},
{"/api/ops/health", "linkHealth"},
}
handler := NewHandler(NewService(NewMockStore()))

View File

@@ -309,8 +309,8 @@ func (m *MockStore) QualitySummary(_ context.Context, query url.Values) (Quality
func mockQualityRows() []QualityIssueRow {
return []QualityIssueRow{
{VIN: "unknown", Plate: "", Protocol: "JT808", IssueType: "VIN_MISSING", Severity: "warning", LastSeen: "2026-07-03 19:58:00", Detail: "phone 13300000001 未命中 binding 表"},
{VIN: "LNXNEGRR7SR318212", Plate: "川AHTWO1", Protocol: "GB32960", IssueType: "LINK_GAP", Severity: "error", LastSeen: "2026-07-03 18:20:00", Detail: "Hyundai 平台近 60 分钟无转发"},
{VIN: "unknown", Plate: "", Phone: "13300000001", SourceEndpoint: "127.0.0.1:808", Protocol: "JT808", IssueType: "VIN_MISSING", Severity: "warning", LastSeen: "2026-07-03 19:58:00", Detail: "phone 13300000001 未命中 binding 表"},
{VIN: "LNXNEGRR7SR318212", Plate: "川AHTWO1", Phone: "", SourceEndpoint: "Hyundai", Protocol: "GB32960", IssueType: "LINK_GAP", Severity: "error", LastSeen: "2026-07-03 18:20:00", Detail: "Hyundai 平台近 60 分钟无转发"},
}
}

View File

@@ -151,13 +151,15 @@ type MileageSummary struct {
}
type QualityIssueRow struct {
VIN string `json:"vin"`
Plate string `json:"plate"`
Protocol string `json:"protocol"`
IssueType string `json:"issueType"`
Severity string `json:"severity"`
LastSeen string `json:"lastSeen"`
Detail string `json:"detail"`
VIN string `json:"vin"`
Plate string `json:"plate"`
Phone string `json:"phone"`
SourceEndpoint string `json:"sourceEndpoint"`
Protocol string `json:"protocol"`
IssueType string `json:"issueType"`
Severity string `json:"severity"`
LastSeen string `json:"lastSeen"`
Detail string `json:"detail"`
}
type QualitySummary struct {

View File

@@ -513,13 +513,15 @@ func (s *ProductionStore) QualityIssues(ctx context.Context, query url.Values) (
return Page[QualityIssueRow]{}, err
}
items = append(items, QualityIssueRow{
VIN: vin,
Plate: plate,
Protocol: "JT808",
IssueType: "VIN_MISSING",
Severity: "warning",
LastSeen: lastSeen,
Detail: fmt.Sprintf("phone %s 未命中 binding 表,来源 %s", phone, source),
VIN: vin,
Plate: plate,
Phone: phone,
SourceEndpoint: source,
Protocol: "JT808",
IssueType: "VIN_MISSING",
Severity: "warning",
LastSeen: lastSeen,
Detail: fmt.Sprintf("phone %s 未命中 binding 表,来源 %s", phone, source),
})
}
return Page[QualityIssueRow]{Items: items, Total: total, Limit: limit, Offset: offset}, rows.Err()

View File

@@ -143,6 +143,8 @@ export interface MileageSummary {
export interface QualityIssueRow {
vin: string;
plate: string;
phone: string;
sourceEndpoint: string;
protocol: string;
issueType: string;
severity: string;

View File

@@ -118,7 +118,7 @@ export function Quality({ onHealthLoaded }: { onHealthLoaded?: (health: OpsHealt
loadSummary(nextFilters);
loadIssues(nextFilters, 1, pagination.pageSize);
}} style={{ marginBottom: 12 }}>
<Form.Input field="keyword" label="关键词" placeholder="手机号 / 来源地址 / 车牌" style={{ width: 240 }} />
<Form.Input field="keyword" label="关键词" placeholder="手机号 / 来源地址 / 车牌" style={{ width: 260 }} />
<Form.Select field="protocol" label="协议" placeholder="全部协议" style={{ width: 160 }}>
<Select.Option value="JT808">JT808</Select.Option>
</Form.Select>
@@ -146,6 +146,8 @@ export function Quality({ onHealthLoaded }: { onHealthLoaded?: (health: OpsHealt
columns={[
{ title: 'VIN', dataIndex: 'vin' },
{ title: '车牌', dataIndex: 'plate' },
{ title: '手机号', dataIndex: 'phone' },
{ title: '来源地址', dataIndex: 'sourceEndpoint' },
{ title: '协议', dataIndex: 'protocol' },
{ title: '问题', dataIndex: 'issueType' },
{ title: '级别', render: (_: unknown, row: QualityIssueRow) => <Tag color={row.severity === 'error' ? 'red' : 'orange'}>{row.severity}</Tag> },