feat(platform): add customer task dispatch
This commit is contained in:
@@ -75,6 +75,14 @@ const customerPrimaryPath = [
|
||||
{ label: '告警通知', page: 'alert-events' as const }
|
||||
];
|
||||
|
||||
const customerTaskPath = [
|
||||
{ label: '地图看车', question: '车辆在哪里', page: 'map' as const },
|
||||
{ label: '轨迹回放', question: '这段时间怎么跑', page: 'history' as const },
|
||||
{ label: '统计查询', question: '里程怎么算', page: 'mileage' as const },
|
||||
{ label: '数据导出', question: '证据怎么给客户', page: 'history-query' as const },
|
||||
{ label: '告警通知', question: '异常谁处理', page: 'alert-events' as const }
|
||||
];
|
||||
|
||||
function linkHealthClassName(count: number | null) {
|
||||
if (count == null) {
|
||||
return '';
|
||||
@@ -193,6 +201,26 @@ export function AppShell({
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="vp-customer-task-dispatch" aria-label="客户任务分发台">
|
||||
<div className="vp-customer-task-dispatch-head">
|
||||
<strong>客户任务分发台</strong>
|
||||
<span>输入 VIN / 车牌 / 手机号后,地图、轨迹、统计、导出和告警都围绕同一辆车服务。</span>
|
||||
</div>
|
||||
<div className="vp-customer-task-dispatch-actions">
|
||||
{customerTaskPath.map((item) => (
|
||||
<button
|
||||
key={item.page}
|
||||
type="button"
|
||||
className={selectedPage === item.page ? 'vp-customer-task-dispatch-action vp-customer-task-dispatch-action-active' : 'vp-customer-task-dispatch-action'}
|
||||
onClick={() => onChange(item.page)}
|
||||
aria-label={`客户任务 ${item.label} ${item.question}`}
|
||||
>
|
||||
<strong>{item.label}</strong>
|
||||
<span>{item.question}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="vp-nav-groups">
|
||||
{navGroups.map((group) => (
|
||||
|
||||
@@ -126,6 +126,74 @@ body {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch {
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid rgba(22, 100, 255, 0.12);
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-head {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-head strong {
|
||||
color: var(--vp-text);
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-head span {
|
||||
color: var(--vp-text-muted);
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-actions {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-action {
|
||||
min-height: 42px;
|
||||
padding: 7px 8px;
|
||||
border: 1px solid var(--vp-border);
|
||||
border-radius: 7px;
|
||||
background: #fff;
|
||||
color: var(--vp-text);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-action strong {
|
||||
font-size: 12px;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-action span {
|
||||
color: var(--vp-text-muted);
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-action:hover,
|
||||
.vp-customer-task-dispatch-action:focus-visible,
|
||||
.vp-customer-task-dispatch-action-active {
|
||||
border-color: rgba(22, 100, 255, 0.38);
|
||||
background: #ffffff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.vp-customer-task-dispatch-action-active strong,
|
||||
.vp-customer-task-dispatch-action:hover strong,
|
||||
.vp-customer-task-dispatch-action:focus-visible strong {
|
||||
color: var(--vp-primary);
|
||||
}
|
||||
|
||||
.vp-nav-groups {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
|
||||
@@ -24,6 +24,13 @@ test('renders vehicle platform shell', () => {
|
||||
expect(screen.getByText('实时地图 / 轨迹统计 / 告警通知')).toBeInTheDocument();
|
||||
expect(screen.getByText('客户主线')).toBeInTheDocument();
|
||||
expect(screen.getByText('先看车,再查时间窗,最后导出和通知。')).toBeInTheDocument();
|
||||
expect(screen.getByText('客户任务分发台')).toBeInTheDocument();
|
||||
expect(screen.getByText('输入 VIN / 车牌 / 手机号后,地图、轨迹、统计、导出和告警都围绕同一辆车服务。')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户任务 地图看车 车辆在哪里' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户任务 轨迹回放 这段时间怎么跑' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户任务 统计查询 里程怎么算' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户任务 数据导出 证据怎么给客户' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户任务 告警通知 异常谁处理' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户主线 车辆地图' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户主线 轨迹回放' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '客户主线 统计查询' })).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user