| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- <!doctype html>
- <html lang="zh-CN">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="referrer" content="no-referrer">
- <title>实时推送检测 · bot-28</title>
- <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='9' fill='%230f766e'/%3E%3Cpath d='M6 17h5l3-8 4 15 3-7h5' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E">
- <link rel="stylesheet" href="./static/css/realtime-test.css">
- <script defer src="./static/vendor/realtime/pusher-8.4.0.min.js"></script>
- <script defer src="./static/vendor/realtime/laravel-echo-2.1.6.js"></script>
- <script type="module" src="./static/js/realtime-test.js"></script>
- </head>
- <body>
- <div class="page">
- <header class="page-header">
- <div>
- <div class="eyebrow"><span class="brand-mark" aria-hidden="true">↗</span> BOT-28 <span class="eyebrow-divider">/</span> REALTIME CHECK</div>
- <h1>实时推送检测</h1>
- <p class="intro">从连接到收到消息,逐步确认后台推送是否正常。</p>
- </div>
- <div id="connection-pill" class="pill" role="status"><span class="dot"></span><span id="connection-label">未连接</span></div>
- </header>
- <main>
- <div id="global-error" class="notice error" role="alert" hidden></div>
- <noscript><div class="notice error">此页面需要启用 JavaScript。</div></noscript>
- <div class="workspace">
- <section class="card setup-card" aria-labelledby="setup-title">
- <div class="section-heading"><span class="section-number">01</span><h2 id="setup-title">连接设置</h2></div>
- <form id="config-form">
- <label for="api-base">后台 API 地址</label>
- <input id="api-base" type="url" inputmode="url" placeholder="https://api.example.com" autocomplete="url" required>
- <p class="field-help">填写 bot-28 的 API 地址,通常与 WebSocket 公网域名相同。</p>
- <label for="admin-token">管理员 token</label>
- <div class="token-field">
- <input id="admin-token" type="password" placeholder="粘贴后台登录 token" autocomplete="off" spellcheck="false" required>
- <button id="toggle-token" class="icon-button" type="button" aria-label="显示 token" aria-pressed="false">显示</button>
- </div>
- <p class="field-help">支持带 Bearer 前缀。本页不会保存 token,刷新后清空。</p>
- <button id="load-config" class="button primary full-width" type="submit">获取连接配置 <span aria-hidden="true">→</span></button>
- </form>
- <div id="config-summary" class="config-summary" hidden>
- <div class="summary-topline"><span class="dot green"></span> 已读取后端配置</div>
- <dl>
- <div><dt>WebSocket</dt><dd id="ws-address">—</dd></div>
- <div><dt>当前序号</dt><dd id="config-seq">—</dd></div>
- <div><dt>登录到期</dt><dd id="session-expiry">—</dd></div>
- </dl>
- <details><summary>查看公开连接参数</summary><pre id="config-json"></pre></details>
- </div>
- <div class="connection-actions">
- <button id="connect" class="button primary" type="button" disabled>连接 WebSocket</button>
- <button id="disconnect" class="button secondary" type="button" disabled>断开</button>
- </div>
- <p class="small-note">只读取配置、授权和消息,不创建订单或修改业务数据。建议通过 API 域名下的本页地址打开;本页域名需在 REVERB_ALLOWED_ORIGINS 中允许。</p>
- </section>
- <div class="right-column">
- <section class="card progress-card" aria-labelledby="progress-title">
- <div class="section-heading"><span class="section-number">02</span><h2 id="progress-title">检测结果</h2><span id="progress-count" class="muted small">0 / 4 通过</span></div>
- <ol class="checks">
- <li id="check-api" data-status="idle"><span class="check-icon">1</span><div><strong>读取配置</strong><span id="check-api-note">等待获取后台配置</span></div><span class="check-state">待检查</span></li>
- <li id="check-ws" data-status="idle"><span class="check-icon">2</span><div><strong>WebSocket 连接</strong><span id="check-ws-note">等待连接 Reverb</span></div><span class="check-state">待检查</span></li>
- <li id="check-auth" data-status="idle"><span class="check-icon">3</span><div><strong>频道授权与订阅</strong><span id="check-auth-note">使用当前管理员的频道权限</span></div><span class="check-state">待检查</span></li>
- <li id="check-live" data-status="idle"><span class="check-icon">4</span><div><strong>接收实时事件</strong><span id="check-live-note">连接后,在另一后台页面触发一条真实业务变更</span></div><span class="check-state">待验证</span></li>
- </ol>
- <p id="verdict" class="verdict">连接成功仅代表通道可用;收到实时事件后,才能确认业务 → relay → Reverb 的链路。</p>
- </section>
- <section class="card channels-card" aria-labelledby="channels-title">
- <div class="section-heading"><span class="section-number">03</span><h2 id="channels-title">订阅频道</h2><span id="channel-count" class="muted small">尚未读取</span></div>
- <div class="channel-toolbar"><div><button id="select-all" class="text-button" type="button" disabled>全选</button><span class="muted">/</span><button id="select-none" class="text-button" type="button" disabled>清空选择</button></div><button id="apply-channels" class="button secondary compact" type="button" disabled>应用订阅</button></div>
- <div id="channel-list" class="channel-list"><div class="empty compact-empty">读取配置后,在这里选择有权限的频道。</div></div>
- <div class="replay-controls">
- <div><label for="after-seq">补发起点 <span class="optional">选填</span></label><input id="after-seq" type="number" min="0" step="1" placeholder="留空:按各频道续传点"></div>
- <button id="replay" class="button secondary" type="button" disabled>检查补发</button>
- </div>
- <p class="field-help">可先断开、触发业务变更,再连接检查补发。补发历史消息不会被误记为实时链路通过。</p>
- </section>
- </div>
- </div>
- <section class="card events-card" aria-labelledby="events-title">
- <div class="section-heading event-heading"><span class="section-number">04</span><h2 id="events-title">消息记录</h2><div class="event-totals"><span>实时 <strong id="live-count">0</strong></span><span>补发 <strong id="replay-count">0</strong></span><span>重复 <strong id="duplicate-count">0</strong></span></div></div>
- <div class="event-toolbar"><div class="segmented" role="group" aria-label="消息来源筛选"><button type="button" data-filter="all" aria-pressed="true">全部</button><button type="button" data-filter="live" aria-pressed="false">实时</button><button type="button" data-filter="replay" aria-pressed="false">补发</button></div><button id="clear-events" class="text-button" type="button">清空记录</button></div>
- <div class="table-scroll"><table><thead><tr><th>收到时间</th><th>来源</th><th>频道 / 事件</th><th>SEQ</th><th>记录主键</th><th><span class="sr-only">详情</span></th></tr></thead><tbody id="event-rows"></tbody></table></div>
- <div id="events-empty" class="empty"><span class="empty-signal" aria-hidden="true">⌁</span><strong>等待第一条消息</strong><span>完成订阅后,消息将在这里出现。</span></div>
- <details id="event-detail" class="event-detail" hidden><summary>消息详情 <span id="detail-meta"></span></summary><pre id="event-json"></pre></details>
- </section>
- <section class="card logs-card" aria-labelledby="logs-title"><div class="section-heading"><h2 id="logs-title">连接日志</h2><button id="clear-logs" class="text-button" type="button">清空日志</button></div><ol id="logs" aria-live="polite" aria-relevant="additions"><li class="log-entry muted"><time>—</time><span>等待开始检测。</span></li></ol></section>
- </main>
- <footer><span><span class="dot"></span> bot-28 · Reverb + Laravel Echo</span><span>仅用于连接联调 · 最多保留最近 200 条消息</span></footer>
- </div>
- </body>
- </html>
|