import { useState } from 'react'; import { Bar, BarChart, CartesianGrid, LabelList, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; import { ArrowUpRight, Info } from 'lucide-react'; import type { FaultAnalysisRecord, FaultDashboardDimension, FaultDashboardResponse, FaultDashboardScope, FaultDistribution } from '../../../shared/assets/faults'; export type DashboardDrill = (title: string, scope?: FaultDashboardScope, filters?: Record) => void; const colors = ['#ef4444','#f59e0b','#2563eb','#93c5fd','#94a3b8']; export function DashboardPanels({data, drill}:{data:FaultDashboardResponse;drill:DashboardDrill}) { const [dimension,setDimension]=useState<'region'|'level'|'customer'|'model'>('region'); const [metric,setMetric]=useState<'reported'|'vehicles'>('reported'); const [expanded,setExpanded]=useState(false),[matrixExpanded,setMatrixExpanded]=useState(false),[customersExpanded,setCustomersExpanded]=useState(false); const groups=data.distributions[dimension],shown=expanded?groups:groups.slice(0,8); const levels=[...data.distributions.level].sort((a,b)=>(a.value==='未标注'?1:0)-(b.value==='未标注'?1:0)||a.value.localeCompare(b.value,'zh-CN')); const models=matrixExpanded?data.matrix.models:data.matrix.models.slice(0,3); const max=Math.max(1,...data.matrix.cells.map(c=>c.count)); const customers=[...data.distributions.customer].sort((a,b)=>b.vehicles-a.vehicles||b.reported-a.reported); const chartDrill=(datum:unknown,key:FaultDashboardDimension,title:string)=>{const row=(datum as {payload?:FaultDistribution})?.payload;if(row)drill(`${title} · ${row.label}`,'cohort',{[key]:row.value});}; return <>

故障分布与对比

按本期提报队列统计,截至当前的闭环状态。
{([['region','区域'],['level','程度'],['customer','客户'],['model','车型']] as const).map(([key,label])=>)}
{metric==='reported'?<>已闭环 {groups.reduce((n,r)=>n+r.closed,0)}未闭环 {groups.reduce((n,r)=>n+r.unclosed,0)}:按车辆去重 · 辆}
{shown.length?
v.length>12?`${v.slice(0,11)}…`:v}/> {metric==='reported'?<>chartDrill(d,dimension,'故障分布')}>row.unclosed===0?row.reported:''} position="right" fontSize={10} fill="#334155"/>chartDrill(d,dimension,'故障分布')}>:chartDrill(d,dimension,'受影响车辆对应故障')}>}
:

所选条件下暂无故障。

}
点击图表查看对应故障;车辆跨组可能重复,不直接累加。{groups.length>8&&}
查看精确数量与下钻{groups.map(r=>)}
分组故障量已闭环未闭环车辆
{r.reported}{r.closed}{r.unclosed}{r.vehicles}

故障程度

现有等级口径

按本期故障数量统计,点击等级查看明细。

{levels.map(row=>)}
{!levels.length&&

暂无等级统计。

}

等级不等于实际停运影响,请结合车辆状态与服务记录判断。

未标注等级 {data.quality.missingLevel} 单;停运车辆与修复时长待补数据。

品牌车型 × 故障部位

点击交叉单元格查看对应故障。
{data.matrix.categories.map(c=>)}{models.map(m=>{data.matrix.categories.map(c=>{const count=data.matrix.cells.find(cell=>cell.model===m.value&&cell.category===c.value)?.count||0;return })})}
品牌车型{c.label}合计
{m.label}
{!models.length&&

暂无车型与部位数据。

}
一单多部位分别计入,合计按故障单去重。{data.matrix.models.length>3&&}

客户受影响情况

同一车辆在同一客户下去重。
{(customersExpanded?customers:customers.slice(0,4)).map((r,i)=>)}
#客户名称本期影响车辆当前在办
{i+1}
{!customers.length&&

暂无客户影响数据。

}
当前在办不限制提报日期;库存车单独展示。{customers.length>4&&}
; } export function DashboardTicketTable({rows,updatedAt,drill,emptyMessage='当前条件下暂无故障。'}:{rows:FaultAnalysisRecord[];updatedAt:string;drill:DashboardDrill;emptyMessage?:string}) { return
{rows.map(row=>{const overdue=['待处理','处理中'].includes(row.status)&&row.deadlineAt&&Date.parse(`${row.deadlineAt.replace(' ','T')}+08:00`)})}
车辆 / 故障单号运维处置人区域 / 客户等级当前状态处置记录 / 故障描述提报时间操作
{row.plate}{row.code}{row.handlers.map(h=>h.label).join('、')}{row.cell.region}{row.customerLabel}{row.level||'未标注'}{row.status==='已归档'?'已闭环':row.status}{overdue&&已逾期}{row.progress||row.description||'暂无处置记录'}{row.reportedAt||'未记录'}
{!rows.length&&

{emptyMessage}

}
; }