feat(web): refine Semi UI access workspace

This commit is contained in:
lingniu
2026-07-20 00:12:46 +08:00
parent cd13a2952d
commit 58ab1ff7bb
5 changed files with 135 additions and 69 deletions

View File

@@ -201,30 +201,30 @@ const AccessVehicleTable = memo(function AccessVehicleTable({ rows, selectedVIN,
render: (_: string, row: AccessVehicleRow) => <div className="v2-access-primary-cell"><strong>{row.plate || '未绑定车牌'}</strong><span>{row.vin}</span></div>
},
{
title: '品牌 / 车型', dataIndex: 'oem', width: 140, fixed: 'left' as const, className: 'v2-access-model-column',
render: (_: string, row: AccessVehicleRow) => <div className="v2-access-primary-cell"><strong>{row.oem || '品牌未维护'}</strong><span>{row.model || row.company || '车型未维护'}</span></div>
title: '差异结论', dataIndex: 'connectionState', width: 220, fixed: 'left' as const, className: 'v2-access-difference-column',
render: (_: AccessVehicleRow['connectionState'], row: AccessVehicleRow) => <ConnectionState row={row} />
},
...PROTOCOLS.map((protocol) => ({
title: <AccessProtocolTitle protocol={protocol} compact />, dataIndex: protocol, width: 160,
title: <AccessProtocolTitle protocol={protocol} compact />, dataIndex: protocol, width: 150,
render: (_: unknown, row: AccessVehicleRow) => <ProtocolState protocol={protocol} status={statusByProtocol(row, protocol)} />
})),
{
title: '差异摘要', dataIndex: 'connectionState', width: 220,
render: (_: AccessVehicleRow['connectionState'], row: AccessVehicleRow) => <ConnectionState row={row} />
title: '品牌 / 车型', dataIndex: 'oem', width: 140, className: 'v2-access-model-column',
render: (_: string, row: AccessVehicleRow) => <div className="v2-access-primary-cell"><strong>{row.oem || '品牌未维护'}</strong><span>{row.model || row.company || '车型未维护'}</span></div>
}
], []);
return <Table
className="v2-access-semi-table"
style={{ width: '100%' }}
scroll={{ x: 1005 }}
scroll={{ x: 975 }}
columns={columns}
dataSource={rows}
rowKey="vin"
pagination={false}
empty={null}
onRow={(row) => row ? detailTriggerRow({
className: selectedVIN === row.vin ? 'is-selected' : '',
className: [`is-state-${row.connectionState}`, selectedVIN === row.vin ? 'is-selected' : ''].filter(Boolean).join(' '),
expanded: selectedVIN === row.vin,
label: `查看 ${row.plate || row.vin} 接入详情`,
testId: `access-row-${row.vin}`,
@@ -433,10 +433,10 @@ export default function AccessPage() {
<WorkspaceCommandBar
className="v2-access-command-bar"
ariaLabel="接入管理操作"
title="真实来源与接入健康"
title="接入健康工作台"
description={mobileLayout
? summary ? `截至 ${compactTime(summary.asOf)} · ${summary.totalVehicles.toLocaleString('zh-CN')} 辆主车辆` : '正在读取最新接入状态'
: '真实来源、在线健康与资料差异一处核对'}
: '核对真实来源、在线状态与车辆档案差异'}
status={summary ? `${summary.totalVehicles.toLocaleString('zh-CN')} 辆主车辆` : '正在读取车辆'}
meta={<Typography.Text type="tertiary"> <AccessTime value={summary?.asOf} /></Typography.Text>}
actions={mobileLayout ? <>
@@ -509,8 +509,8 @@ export default function AccessPage() {
<div className="v2-access-workspace-v3">
<Card className="v2-access-table-v3" bodyStyle={{ padding: 0 }}>
<WorkspacePanelHeader
title={scopeLabels[criteria.connectionState] || '车辆接入清单'}
description="缺席协议仅表示当前未发现;优先核对异常、离线与资料差异"
title="接入差异清单"
description={`当前范围:${scopeLabels[criteria.connectionState] || '全部主车辆'} · 缺席协议仅表示当前未发现`}
actionsClassName="v2-access-table-actions"
actions={mobileLayout ? null : <Button theme="light" icon={<IconDownload />} onClick={() => downloadRows(rows)} disabled={!rows.length}></Button>}
/>
@@ -530,7 +530,7 @@ export default function AccessPage() {
onKeyDown={scrollAccessTable}
>
{mobileLayout
? <div className="v2-access-mobile-list">{rows.map((row) => <Card key={row.vin} className={`v2-access-mobile-card${selected?.vin === row.vin ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" aria-pressed={selected?.vin === row.vin} aria-expanded={selected?.vin === row.vin} aria-label={`查看 ${row.plate || row.vin} 接入详情`} className="v2-access-mobile-action" onClick={() => setSelectedVIN(row.vin)}><span className="v2-access-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><ConnectionState row={row} /></header><p className={row.connectionState === 'healthy' ? '' : 'is-issue'} title={row.connectionState === 'healthy' ? undefined : accessIssueSummary(row)}>{row.connectionState === 'healthy' ? `${row.oem || '品牌未维护'} · ${row.model || row.company || '车型未维护'}` : `${accessIssueSummary(row)} · ${row.oem || '品牌未维护'} ${row.model || row.company || '车型未维护'}`}</p><span className="v2-access-mobile-protocols">{PROTOCOLS.map((protocol) => <ProtocolState key={protocol} protocol={protocol} protocolLabel={compactProtocolLabel(protocol)} status={statusByProtocol(row, protocol)} />)}</span><footer><IconChevronRight /></footer></span></Button></Card>)}</div>
? <div className="v2-access-mobile-list">{rows.map((row) => <Card key={row.vin} className={`v2-access-mobile-card is-state-${row.connectionState}${selected?.vin === row.vin ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" aria-pressed={selected?.vin === row.vin} aria-expanded={selected?.vin === row.vin} aria-label={`查看 ${row.plate || row.vin} 接入详情`} className="v2-access-mobile-action" onClick={() => setSelectedVIN(row.vin)}><span className="v2-access-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><ConnectionState row={row} /></header><p className={row.connectionState === 'healthy' ? '' : 'is-issue'} title={row.connectionState === 'healthy' ? undefined : accessIssueSummary(row)}>{row.connectionState === 'healthy' ? `${row.oem || '品牌未维护'} · ${row.model || row.company || '车型未维护'}` : `${accessIssueSummary(row)} · ${row.oem || '品牌未维护'} ${row.model || row.company || '车型未维护'}`}</p><span className="v2-access-mobile-protocols">{PROTOCOLS.map((protocol) => <ProtocolState key={protocol} protocol={protocol} protocolLabel={compactProtocolLabel(protocol)} status={statusByProtocol(row, protocol)} />)}</span><footer><IconChevronRight /></footer></span></Button></Card>)}</div>
: <AccessVehicleTable rows={rows} selectedVIN={selectedVIN} onSelect={setSelectedVIN} />}
{vehiclesQuery.isFetching ? <PanelLoading className="v2-access-loading" title="正在更新车辆接入状态…" description="当前列表返回后会自动替换。" compact={Boolean(rows.length)} /> : null}
{!vehiclesQuery.isFetching && !rows.length ? <PanelEmpty className="v2-access-empty" title="没有匹配车辆" description="调整车牌、协议或接入状态筛选后重试。" /> : null}