refactor: unify guided workspace empty states

This commit is contained in:
lingniu
2026-07-19 12:49:22 +08:00
parent 4e4f383988
commit dffe559160
7 changed files with 367 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import { useMutation, useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';
import { IconChevronRight, IconClose, IconDownload, IconRefresh, IconSearch, IconSetting } from '@douyinfe/semi-icons';
import { IconCalendar, IconChevronRight, IconClose, IconDownload, IconMapPin, IconRefresh, IconSearch, IconSetting } from '@douyinfe/semi-icons';
import { Button, Card, CardGroup, Checkbox, Descriptions, Dropdown, Empty, Input, Progress, Select, Spin, Table, Tag, Typography } from '@douyinfe/semi-ui';
import { FormEvent, KeyboardEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
@@ -8,7 +8,7 @@ import type { HistoryDataResponse, HistoryDataRow, HistoryExportJob, HistoryExpo
import { buildHistorySeriesPanels, formatExportFileSize, formatHistoryValue, formatSeriesGrain, historyExportPollInterval, parseHistoryKeywords } from '../domain/history';
import { downloadBlob } from '../domain/download';
import { formatShanghaiDateTime } from '../domain/formatters';
import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
import { InlineError, PanelEmpty, PanelLoading, WorkspaceEmptyGuide } from '../shared/AsyncState';
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
import { MobileFilterToggle } from '../shared/MobileFilterToggle';
import { MobileFilterSheet, MobileFilterSheetSection } from '../shared/MobileFilterSheet';
@@ -593,11 +593,26 @@ export default function HistoryPage() {
{dataQuery.isPending && keywords.length
? <PanelLoading className="v2-history-loading" title="正在加载当前筛选范围的历史数据" description="按车辆、时间和协议整理可追溯证据。" />
: !resultRows.length
? <PanelEmpty className="v2-history-empty"
title={keywords.length ? '当前条件没有历史记录' : '选择车辆开始查询'}
description={keywords.length ? '调整车辆、时间或数据来源后重试。' : '支持车牌或 VIN最多可同时查询 5 台车辆。'}
action={mobileLayout ? <Button className="v2-history-empty-action" theme="solid" icon={<IconSearch />} aria-label={keywords.length ? '调整查询范围' : '选择车辆并查询'} onClick={() => setFiltersCollapsed(false)}>{keywords.length ? '调整查询范围' : '选择车辆并查询'}</Button> : null}
/>
? keywords.length
? <PanelEmpty
className="v2-history-empty"
title="当前条件没有历史记录"
description="调整车辆、时间或数据来源后重试。"
action={<Button className="v2-history-empty-action" theme="light" icon={<IconSearch />} aria-label="调整查询范围" onClick={() => setFiltersCollapsed(false)}></Button>}
/>
: <WorkspaceEmptyGuide
className="v2-history-empty"
eyebrow="从一个明确的车辆范围开始"
icon={<IconSearch />}
title="选择车辆,开始核验历史证据"
description="一次最多查询 5 台车辆,结果会保留协议来源、质量说明与 RAW 证据。"
steps={[
{ icon: <IconSearch />, title: '选择车辆', description: '支持车牌、VIN 与批量粘贴' },
{ icon: <IconCalendar />, title: '确认时间', description: '按上海时区精确到分钟' },
{ icon: <IconMapPin />, title: '核验数据', description: '位置、RAW 与日里程统一检索' }
]}
action={<Button className="v2-history-empty-action" theme="solid" icon={<IconSearch />} aria-label="选择车辆并查询" onClick={() => setFiltersCollapsed(false)}></Button>}
/>
: null}
</div>
{keywords.length ? <footer><TablePagination page={page} totalPages={totalPages} info={`${(result?.total ?? 0).toLocaleString('zh-CN')}`} onPageChange={(next) => setOffset((next - 1) * limit)} pageSize={mobileLayout ? undefined : limit} onPageSizeChange={(next) => { setLimit(next); setOffset(0); }} pageSizeOptions={mobileLayout ? undefined : [{ value: 20, label: '20 条/页' }, { value: 50, label: '50 条/页' }, { value: 100, label: '100 条/页' }]} /></footer> : null}