Files
FT546-WCS/javaTest/src/main/resources/visualizer/index.html

290 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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">
<div class="view-mode" role="group" aria-label="地图视口">
<button id="map-fit" type="button" class="view-mode-button is-active">全图</button>
<button id="path-fit" type="button" class="view-mode-button">路径</button>
</div>
<div class="map-actions" role="group" aria-label="地图缩放">
<button id="zoom-out" type="button" class="icon-button compact" title="缩小地图" aria-label="缩小地图">−</button>
<button id="zoom-in" type="button" class="icon-button compact" title="放大地图" aria-label="放大地图">+</button>
<button id="reset-view" type="button" class="icon-button compact" title="复位为完整地图" aria-label="复位为完整地图">⌂</button>
</div>
<label class="inline-field"><span>楼层</span><select id="floor-select"></select></label>
<div class="layer-toggles" aria-label="路线图层">
<label class="toggle-field"><input id="show-historical" type="checkbox" checked><span>历史</span></label>
<label class="toggle-field"><input id="show-initial-route" type="checkbox" checked><span>初始</span></label>
<label class="toggle-field"><input id="show-current-route" type="checkbox" checked><span>当前</span></label>
<label class="toggle-field"><input id="show-move-trace" type="checkbox" checked><span>MOVE</span></label>
<label class="toggle-field"><input id="show-hold-points" type="checkbox" checked><span>HOLD</span></label>
</div>
</div>
</div>
<div class="route-legend" aria-label="路径图例">
<span><i class="legend-line map-base"></i>完整地图</span>
<span><i class="legend-line approach"></i>接近路径</span>
<span><i class="legend-line shared"></i>共同路段</span>
<span><i class="legend-line planned-only"></i>仅新规划</span>
<span><i class="legend-line historical-only"></i>仅历史</span>
<span><i class="legend-line initial-service"></i>初始规划</span>
<span><i class="legend-line traversed"></i>已通过</span>
<span><i class="legend-line reroute-old"></i>换路前</span>
<span><i class="legend-line reroute-new"></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>
<g id="map-cache-layer"></g>
<g id="dynamic-route-layer"></g>
</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>
<div><dt>路径边差</dt><dd id="route-difference">共同 -- / 新增 -- / 历史 --</dd></div>
<div><dt>历史无效段</dt><dd id="invalid-history-segments">--</dd></div>
</dl>
<section class="decision-audit" aria-labelledby="decision-audit-title">
<div class="inspector-section-bar">
<div>
<span class="section-kicker">路线决策</span>
<h3 id="decision-audit-title">候选与质量</h3>
</div>
<div class="comparison-status">
<span id="route-comparability" class="evidence-badge is-neutral">--</span>
<span id="route-quality-comparison" class="evidence-badge is-neutral">--</span>
</div>
</div>
<div class="decision-selectors">
<label class="inline-field"><span>阶段</span><select id="route-stage-select"><option value="SERVICE">服务段</option><option value="APPROACH">接近段</option></select></label>
<label class="inline-field"><span>版本</span><select id="route-version-select"></select></label>
</div>
<dl id="route-decision-summary" class="decision-summary">
<div><dt>最短距离</dt><dd id="decision-shortest-distance">--</dd></div>
<div><dt>选中距离</dt><dd id="decision-selected-distance">--</dd></div>
<div><dt>绕行比例</dt><dd id="decision-detour-ratio">--</dd></div>
<div><dt>候选数量</dt><dd id="decision-candidate-count">--</dd></div>
<div class="span-all"><dt>选择原因</dt><dd id="decision-reason">--</dd></div>
</dl>
<div class="compact-table-scroll">
<table class="compact-evidence-table quality-table">
<thead><tr><th>质量项</th><th>选中</th><th>历史</th></tr></thead>
<tbody id="route-quality-body"></tbody>
</table>
</div>
<div class="compact-table-scroll candidate-scroll">
<table class="compact-evidence-table candidate-table">
<thead><tr><th>候选路径</th><th>距离</th><th>质量</th></tr></thead>
<tbody id="route-candidate-body"></tbody>
</table>
</div>
</section>
<section class="reroute-audit" aria-labelledby="reroute-audit-title">
<div class="inspector-section-bar">
<div><span class="section-kicker">交通 HOLD</span><h3 id="reroute-audit-title">重规划记录</h3></div>
<select id="reroute-select" aria-label="选择重规划记录"></select>
</div>
<div id="reroute-comparison" class="reroute-comparison">
<div><span>触发 / 结果</span><output id="reroute-reason">--</output></div>
<div><span>换路前</span><output id="reroute-old-path">--</output></div>
<div><span>换路后</span><output id="reroute-new-path">--</output></div>
</div>
</section>
<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>