feat(platform): remove default history vehicle
This commit is contained in:
@@ -16,7 +16,7 @@ import { Vehicles } from './pages/Vehicles';
|
|||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const initialRoute = parseAppHash(window.location.hash);
|
const initialRoute = parseAppHash(window.location.hash);
|
||||||
const initialVehicleKey = initialRoute.keyword || 'LB9A32A24R0LS1426';
|
const initialVehicleKey = initialRoute.keyword || '';
|
||||||
const [activePage, setActivePage] = useState<PageKey>(initialRoute.page ?? 'dashboard');
|
const [activePage, setActivePage] = useState<PageKey>(initialRoute.page ?? 'dashboard');
|
||||||
const [activeVin, setActiveVin] = useState(initialVehicleKey);
|
const [activeVin, setActiveVin] = useState(initialVehicleKey);
|
||||||
const [analysisVin, setAnalysisVin] = useState(initialVehicleKey);
|
const [analysisVin, setAnalysisVin] = useState(initialVehicleKey);
|
||||||
@@ -351,7 +351,8 @@ export default function App() {
|
|||||||
|
|
||||||
const openHistoryWithFilters = (filters: Record<string, string> = {}) => {
|
const openHistoryWithFilters = (filters: Record<string, string> = {}) => {
|
||||||
const nextFilters = normalizeHistoryFilterValues(filters);
|
const nextFilters = normalizeHistoryFilterValues(filters);
|
||||||
const nextVin = nextFilters.keyword?.trim() || analysisVin;
|
const hasKeywordInput = Object.prototype.hasOwnProperty.call(nextFilters, 'keyword');
|
||||||
|
const nextVin = nextFilters.keyword?.trim() || (hasKeywordInput ? '' : analysisVin);
|
||||||
const nextProtocol = nextFilters.protocol?.trim() ?? activeProtocol;
|
const nextProtocol = nextFilters.protocol?.trim() ?? activeProtocol;
|
||||||
const nextTab = nextFilters.tab === 'raw' || nextFilters.tab === 'fields' ? nextFilters.tab : 'location';
|
const nextTab = nextFilters.tab === 'raw' || nextFilters.tab === 'fields' ? nextFilters.tab : 'location';
|
||||||
const nextPage = nextTab === 'raw' || nextTab === 'fields' ? 'history-query' : 'history';
|
const nextPage = nextTab === 'raw' || nextTab === 'fields' ? 'history-query' : 'history';
|
||||||
@@ -385,11 +386,9 @@ export default function App() {
|
|||||||
|
|
||||||
const openRawWithFilters = (filters: Record<string, string> = {}) => {
|
const openRawWithFilters = (filters: Record<string, string> = {}) => {
|
||||||
const nextFilters = normalizeHistoryFilterValues(filters);
|
const nextFilters = normalizeHistoryFilterValues(filters);
|
||||||
const nextVin = nextFilters.keyword?.trim() || analysisVin;
|
const hasKeywordInput = Object.prototype.hasOwnProperty.call(nextFilters, 'keyword');
|
||||||
|
const nextVin = nextFilters.keyword?.trim() || (hasKeywordInput ? '' : analysisVin);
|
||||||
const nextProtocol = nextFilters.protocol?.trim() ?? activeProtocol;
|
const nextProtocol = nextFilters.protocol?.trim() ?? activeProtocol;
|
||||||
if (!nextVin) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setAnalysisVin(nextVin);
|
setAnalysisVin(nextVin);
|
||||||
setActiveProtocol(nextProtocol);
|
setActiveProtocol(nextProtocol);
|
||||||
setHistoryTab('raw');
|
setHistoryTab('raw');
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ type RawFieldRow = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const defaultFilters: HistoryFilters = {
|
const defaultFilters: HistoryFilters = {
|
||||||
keyword: 'LB9A32A24R0LS1426',
|
|
||||||
includeFields: false
|
includeFields: false
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,6 +54,24 @@ function nextDate(value: string) {
|
|||||||
return date.toISOString().slice(0, 10);
|
return date.toISOString().slice(0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function todayDateString() {
|
||||||
|
const date = new Date();
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function previousDateString(value: string) {
|
||||||
|
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
|
||||||
|
if (!match) return value;
|
||||||
|
const date = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]) - 1);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
function splitFields(value?: string) {
|
function splitFields(value?: string) {
|
||||||
return (value ?? '')
|
return (value ?? '')
|
||||||
.split(/[\n,]/)
|
.split(/[\n,]/)
|
||||||
@@ -168,10 +185,24 @@ function analyzeTrajectoryAnomalies(rows: HistoryLocationRow[]): TrajectoryAnoma
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mergeInitialFilters(initialVin: string, initialProtocol?: string, initialFilters: Record<string, string> = {}): HistoryFilters {
|
function mergeInitialFilters(initialVin: string, initialProtocol?: string, initialFilters: Record<string, string> = {}): HistoryFilters {
|
||||||
const hasExplicitFilters = Object.keys(initialFilters).length > 0;
|
const hasExplicitScope = Boolean(
|
||||||
|
initialVin?.trim() ||
|
||||||
|
initialProtocol?.trim() ||
|
||||||
|
initialFilters.keyword?.trim() ||
|
||||||
|
initialFilters.protocol?.trim() ||
|
||||||
|
initialFilters.dateFrom?.trim() ||
|
||||||
|
initialFilters.dateTo?.trim() ||
|
||||||
|
initialFilters.fields?.trim()
|
||||||
|
);
|
||||||
|
const today = todayDateString();
|
||||||
|
const defaultDateRange = hasExplicitScope ? {} : {
|
||||||
|
dateFrom: previousDateString(today),
|
||||||
|
dateTo: today
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
...defaultFilters,
|
...defaultFilters,
|
||||||
keyword: initialVin || (hasExplicitFilters ? '' : defaultFilters.keyword),
|
...defaultDateRange,
|
||||||
|
keyword: initialVin || '',
|
||||||
protocol: initialProtocol,
|
protocol: initialProtocol,
|
||||||
...initialFilters,
|
...initialFilters,
|
||||||
includeFields: isIncludeFieldsEnabled(initialFilters.includeFields)
|
includeFields: isIncludeFieldsEnabled(initialFilters.includeFields)
|
||||||
@@ -1075,6 +1106,9 @@ export function History({
|
|||||||
<Typography.Text type="secondary">
|
<Typography.Text type="secondary">
|
||||||
面向车辆服务的历史数据检索入口。先按车辆和时间缩小范围,再导出位置、原始记录或字段明细,用于客户问询、BI 核对和问题追溯。
|
面向车辆服务的历史数据检索入口。先按车辆和时间缩小范围,再导出位置、原始记录或字段明细,用于客户问询、BI 核对和问题追溯。
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
|
<Typography.Text type="tertiary">
|
||||||
|
默认查询最近一天,不预置任何车辆;输入 VIN、车牌或手机号后进入单车证据交付。
|
||||||
|
</Typography.Text>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button size="small" theme="solid" type="primary" onClick={() => openQueryTab('location')}>查询位置历史</Button>
|
<Button size="small" theme="solid" type="primary" onClick={() => openQueryTab('location')}>查询位置历史</Button>
|
||||||
<Button size="small" onClick={() => openQueryTab('raw')}>查询原始记录</Button>
|
<Button size="small" onClick={() => openQueryTab('raw')}>查询原始记录</Button>
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ test('exposes AMap operations shortcuts when map key is configured', async () =>
|
|||||||
expect(window.location.hash.startsWith('#/history-query')).toBe(true);
|
expect(window.location.hash.startsWith('#/history-query')).toBe(true);
|
||||||
expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('tab')).toBe('raw');
|
expect(new URLSearchParams(window.location.hash.split('?')[1] ?? '').get('tab')).toBe('raw');
|
||||||
expect(await screen.findByRole('heading', { name: '数据导出' })).toBeInTheDocument();
|
expect(await screen.findByRole('heading', { name: '数据导出' })).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('默认查询最近一天,不预置任何车辆;输入 VIN、车牌或手机号后进入单车证据交付。')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByDisplayValue('LB9A32A24R0LS1426')).not.toBeInTheDocument();
|
||||||
fireEvent.click(screen.getByRole('button', { name: '顶部里程统计' }));
|
fireEvent.click(screen.getByRole('button', { name: '顶部里程统计' }));
|
||||||
expect(window.location.hash.startsWith('#/mileage')).toBe(true);
|
expect(window.location.hash.startsWith('#/mileage')).toBe(true);
|
||||||
fireEvent.click(await screen.findByRole('button', { name: '顶部告警事件正常' }));
|
fireEvent.click(await screen.findByRole('button', { name: '顶部告警事件正常' }));
|
||||||
|
|||||||
Reference in New Issue
Block a user