300 lines
16 KiB
HTML
300 lines
16 KiB
HTML
<!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><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>
|
||
<span><i class="legend-transfer"></i>换层端口</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-assignment-mode">--</dd></div>
|
||
<div><dt>涉及楼层</dt><dd id="evidence-involved-floors">--</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 id="floor-transfer-panel" class="floor-transfer-panel" aria-labelledby="floor-transfer-title" hidden>
|
||
<div class="inspector-section-bar">
|
||
<div><span class="section-kicker">设备作业</span><h3 id="floor-transfer-title">换层作业</h3></div>
|
||
<span id="floor-transfer-count" class="evidence-badge is-neutral">0 个</span>
|
||
</div>
|
||
<div id="floor-transfer-list" class="floor-transfer-list"></div>
|
||
</section>
|
||
<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>
|