feat(javaTest): add dispatch audit visualizer
This commit is contained in:
219
javaTest/src/main/resources/visualizer/index.html
Normal file
219
javaTest/src/main/resources/visualizer/index.html
Normal file
@@ -0,0 +1,219 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="color-scheme" content="light">
|
||||
<link rel="icon" href="data:,">
|
||||
<title>javaTest 调度路径审计台</title>
|
||||
<link rel="stylesheet" href="/assets/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<header id="app-header" class="app-header">
|
||||
<div class="brand-block">
|
||||
<span class="brand-mark" aria-hidden="true"><i></i><i></i><i></i></span>
|
||||
<div>
|
||||
<h1>调度路径审计台</h1>
|
||||
<p id="boundary-text">离线内存仿真</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-status">
|
||||
<span id="service-status" class="status-chip status-pending">服务连接中</span>
|
||||
<span id="acceptance-status" class="status-chip status-neutral">尚未验收</span>
|
||||
<span id="map-version" class="meta-value">地图 --</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav id="mode-tabs" class="mode-tabs" aria-label="审计模式">
|
||||
<button type="button" class="mode-tab is-active" data-mode="point" aria-selected="true">A → B 单任务</button>
|
||||
<button type="button" class="mode-tab" data-mode="history" aria-selected="false">240 条历史任务</button>
|
||||
<button type="button" class="mode-tab" data-mode="safety" aria-selected="false">安全审计</button>
|
||||
</nav>
|
||||
|
||||
<section id="point-controls" class="control-band" aria-label="单任务参数">
|
||||
<form id="point-form" class="point-form">
|
||||
<label class="field field-site">
|
||||
<span>起点 A</span>
|
||||
<input id="source-site" name="sourceSite" list="site-options" autocomplete="off" required>
|
||||
</label>
|
||||
<button id="swap-sites" type="button" class="icon-button" title="交换起点和终点" aria-label="交换起点和终点">⇄</button>
|
||||
<label class="field field-site">
|
||||
<span>终点 B</span>
|
||||
<input id="target-site" name="targetSite" list="site-options" autocomplete="off" required>
|
||||
</label>
|
||||
<datalist id="site-options"></datalist>
|
||||
<label class="field">
|
||||
<span>任务类型</span>
|
||||
<select id="task-type" name="taskType">
|
||||
<option value="INBOUND">入库</option>
|
||||
<option value="OUTBOUND">出库</option>
|
||||
<option value="RELOCATION">移位</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field field-compact">
|
||||
<span>优先级</span>
|
||||
<input id="priority" name="priority" type="number" min="0" max="9" value="1" required>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>加速</span>
|
||||
<select id="acceleration" name="acceleration">
|
||||
<option value="100">100×</option>
|
||||
<option value="10">10×</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field field-fault">
|
||||
<span>故障预设</span>
|
||||
<select id="fault-preset" name="faultPreset">
|
||||
<option value="NONE">无故障</option>
|
||||
<option value="PLC_FIRST_SEND_FAILURE">PLC 首次发送失败</option>
|
||||
<option value="VEHICLE_RESTART">车辆重启</option>
|
||||
<option value="LOW_BATTERY">全车低电量后恢复</option>
|
||||
<option value="DISCONNECT_RECONNECT">全车断线后重连</option>
|
||||
</select>
|
||||
</label>
|
||||
<button id="run-point" type="submit" class="primary-button"><span aria-hidden="true">▶</span>运行调度</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section id="history-controls" class="history-band" hidden>
|
||||
<div class="history-actions">
|
||||
<div>
|
||||
<strong>真实历史负载</strong>
|
||||
<span id="history-run-state">尚未运行</span>
|
||||
</div>
|
||||
<div class="button-row">
|
||||
<button id="export-result" type="button" class="secondary-button" disabled>导出证据</button>
|
||||
<button id="run-history" type="button" class="primary-button"><span aria-hidden="true">▶</span>运行 240 条</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="history-kpis" class="kpi-strip"></div>
|
||||
<div class="table-toolbar">
|
||||
<label class="search-field"><span class="sr-only">搜索任务</span><input id="task-search" type="search" placeholder="任务号 / 站点 / 车辆"></label>
|
||||
<select id="task-status-filter" aria-label="按任务状态筛选">
|
||||
<option value="ALL">全部状态</option>
|
||||
<option value="COMPLETED">完成</option>
|
||||
<option value="WAITING">等待</option>
|
||||
<option value="FAILED">失败</option>
|
||||
</select>
|
||||
<span id="task-filter-count" class="table-count">0 条</span>
|
||||
</div>
|
||||
<div class="table-scroll history-table-scroll">
|
||||
<table class="data-table history-table">
|
||||
<thead><tr><th>任务</th><th>A → B</th><th>优先级</th><th>历史车</th><th>模拟车</th><th>路径</th><th>状态</th><th>等待</th><th>完成</th></tr></thead>
|
||||
<tbody id="history-task-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main id="task-workspace" class="workspace">
|
||||
<section id="route-stage" class="route-stage" aria-labelledby="route-title">
|
||||
<div class="section-bar">
|
||||
<div>
|
||||
<span class="section-kicker">真实地图坐标</span>
|
||||
<h2 id="route-title">算法规划路径</h2>
|
||||
</div>
|
||||
<div class="route-tools">
|
||||
<label class="inline-field"><span>楼层</span><select id="floor-select"></select></label>
|
||||
<label class="toggle-field"><input id="show-historical" type="checkbox" checked><span>历史参考</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="route-legend" aria-label="路径图例">
|
||||
<span><i class="legend-line approach"></i>接近路径</span>
|
||||
<span><i class="legend-line service"></i>A → B 规划</span>
|
||||
<span><i class="legend-line traversed"></i>已通过</span>
|
||||
<span><i class="legend-line historical"></i>历史参考</span>
|
||||
<span><i class="legend-dot hold"></i>HOLD</span>
|
||||
</div>
|
||||
<div class="route-canvas-wrap">
|
||||
<svg id="route-map" viewBox="0 0 1000 560" role="img" aria-label="调度中心规划路径">
|
||||
<defs>
|
||||
<pattern id="map-grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||
<path d="M 40 0 L 0 0 0 40" class="grid-line"></path>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="1000" height="560" class="map-background"></rect>
|
||||
</svg>
|
||||
<div id="route-empty" class="empty-state">
|
||||
<strong>等待调度结果</strong>
|
||||
<span>路径证据将在本区域显示</span>
|
||||
</div>
|
||||
<div id="loading-state" class="loading-state" hidden>
|
||||
<span class="activity-indicator" aria-hidden="true"></span>
|
||||
<strong id="loading-label">正在运行调度</strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside id="task-inspector" class="task-inspector" aria-label="任务检查器">
|
||||
<div class="section-bar inspector-heading">
|
||||
<div><span class="section-kicker">任务证据</span><h2 id="inspector-task-id">未选择任务</h2></div>
|
||||
<span id="task-status" class="status-chip status-neutral">--</span>
|
||||
</div>
|
||||
<dl class="evidence-list">
|
||||
<div><dt>业务端点</dt><dd id="evidence-endpoints">--</dd></div>
|
||||
<div><dt>中心选车</dt><dd id="evidence-vehicle">--</dd></div>
|
||||
<div><dt>历史车辆</dt><dd id="evidence-history-vehicle">--</dd></div>
|
||||
<div><dt>首次分配</dt><dd id="evidence-assigned-time">--</dd></div>
|
||||
<div><dt>等待时间</dt><dd id="evidence-waiting">--</dd></div>
|
||||
<div><dt>完成时间</dt><dd id="evidence-completion">--</dd></div>
|
||||
<div><dt>HOLD / 重试</dt><dd id="evidence-hold-retry">--</dd></div>
|
||||
<div><dt>PLC 尝试</dt><dd id="evidence-plc">--</dd></div>
|
||||
</dl>
|
||||
<div class="path-proof">
|
||||
<span>调度中心 plannedPath</span>
|
||||
<output id="planned-path-output">--</output>
|
||||
</div>
|
||||
<div class="reason-proof">
|
||||
<span>终态 / 当前原因</span>
|
||||
<output id="reason-output">--</output>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
|
||||
<section id="timeline-panel" class="timeline-panel" aria-labelledby="timeline-title">
|
||||
<div class="timeline-controls">
|
||||
<div>
|
||||
<span class="section-kicker">逐 tick 证据</span>
|
||||
<h2 id="timeline-title">调度时间线</h2>
|
||||
</div>
|
||||
<div class="playback-buttons" role="group" aria-label="时间线播放控制">
|
||||
<button id="step-back" type="button" class="icon-button" title="上一个事件" aria-label="上一个事件">◀</button>
|
||||
<button id="play-timeline" type="button" class="icon-button" title="播放" aria-label="播放">▶</button>
|
||||
<button id="pause-timeline" type="button" class="icon-button" title="暂停" aria-label="暂停">Ⅱ</button>
|
||||
<button id="step-forward" type="button" class="icon-button" title="下一个事件" aria-label="下一个事件">▶</button>
|
||||
</div>
|
||||
<span id="tick-readout" class="tick-readout">tick --</span>
|
||||
<input id="timeline-slider" type="range" min="0" max="0" value="0" aria-label="调度 tick">
|
||||
<label class="inline-field speed-field"><span>速度</span><select id="playback-speed"><option value="900">0.5×</option><option value="450" selected>1×</option><option value="220">2×</option><option value="90">5×</option></select></label>
|
||||
</div>
|
||||
<div class="table-toolbar timeline-filter-bar">
|
||||
<select id="event-type-filter" aria-label="按事件类型筛选"><option value="ALL">全部事件</option></select>
|
||||
<span id="event-count" class="table-count">0 个事件</span>
|
||||
</div>
|
||||
<div class="table-scroll event-table-scroll">
|
||||
<table class="data-table event-table">
|
||||
<thead><tr><th>tick</th><th>事件</th><th>车辆</th><th>原因</th><th>移动</th></tr></thead>
|
||||
<tbody id="event-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="safety-view" class="safety-view" hidden>
|
||||
<div class="safety-header">
|
||||
<div><span class="section-kicker">验收门禁</span><h2>资源安全与幂等</h2></div>
|
||||
<button id="export-safety" type="button" class="secondary-button" disabled>导出证据</button>
|
||||
</div>
|
||||
<div id="safety-metrics" class="audit-grid"></div>
|
||||
<div class="reason-columns">
|
||||
<section><h3>HOLD 原因</h3><div id="hold-reasons" class="reason-list"></div></section>
|
||||
<section><h3>PLC 重试原因</h3><div id="retry-reasons" class="reason-list"></div></section>
|
||||
<section><h3>失败原因</h3><div id="failure-reasons" class="reason-list"></div></section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="toast" class="toast" role="status" aria-live="polite" hidden></div>
|
||||
</div>
|
||||
<script src="/assets/app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user