215 lines
47 KiB
HTML
215 lines
47 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>羚牛 · 车辆数据开放平台</title>
|
||
<style>
|
||
:root{color-scheme:light;--page:#f5f5f7;--surface:#fff;--ink:#1d1d1f;--muted:#6e6e73;--line:rgba(0,0,0,.10);--blue:#0071e3;--blue-soft:#e8f2ff;--green:#007a46;--code:#1d1d1f;--radius:18px;--sidebar:264px}
|
||
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;font:15px/1.58 -apple-system,BlinkMacSystemFont,"SF Pro Text","PingFang SC","Microsoft YaHei",sans-serif;color:var(--ink);background:var(--page);-webkit-font-smoothing:antialiased}
|
||
a{color:inherit;text-decoration:none}.layout{min-height:100vh;display:grid;grid-template-columns:var(--sidebar) minmax(0,1fr)}
|
||
.sidebar{position:sticky;top:0;height:100vh;padding:26px 14px 20px;border-right:1px solid var(--line);background:rgba(255,255,255,.84);backdrop-filter:blur(18px);overflow-y:auto}.brand{display:block;padding:7px 11px 27px}.brand-name{display:block;font-size:17px;font-weight:650;letter-spacing:-.02em}.brand-subtitle{display:block;margin-top:3px;color:var(--muted);font-size:12px}
|
||
.nav-group{padding:15px 0 5px;border-top:1px solid var(--line)}.nav-group:first-of-type{border-top:0;padding-top:0}.nav-title{display:block;padding:0 11px 7px;color:var(--muted);font-size:12px;font-weight:600}.nav-link{display:flex;align-items:center;gap:10px;margin:2px 0;padding:8px 11px;border-radius:9px;color:#424245;font-size:14px}.nav-link:hover{color:var(--blue);background:#f3f7fc}.nav-link::before{content:"";width:5px;height:5px;border-radius:50%;background:#c7c7cc;flex:0 0 auto}.nav-link.primary::before{background:var(--blue)}.nav-link.station::before{background:var(--green)}.nav-link.docs::before{width:6px;height:6px;border-radius:2px;background:#8e8e93}.external{display:inline-flex;align-items:center;gap:8px;margin:22px 11px 0;padding:9px 10px;color:var(--blue);font-size:13px;font-weight:550}.external svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.8}
|
||
.content{max-width:1200px;width:100%;padding:48px 56px 96px}.intro{padding:0 0 34px;border-bottom:1px solid var(--line)}h1{margin:0;letter-spacing:-.04em;font-size:40px;line-height:1.15;font-weight:680}.intro p{max-width:720px;margin:13px 0 0;color:var(--muted);font-size:16px}.base-url{display:inline-flex;gap:8px;align-items:center;margin-top:21px;padding:8px 11px;border:1px solid var(--line);border-radius:9px;background:var(--surface);font:12px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}.base-url code{color:var(--blue)}
|
||
.section{scroll-margin-top:26px;padding:36px 0;border-bottom:1px solid var(--line)}.section:target{margin:0 -18px;padding-right:18px;padding-left:18px;border-radius:var(--radius);background:rgba(0,113,227,.035);border-bottom-color:transparent}.section:last-child{border-bottom:0}.section-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}.section h2{margin:0;font-size:24px;letter-spacing:-.025em;line-height:1.25}.section p{margin:8px 0 0;color:var(--muted)}.endpoint{display:inline-flex;align-items:center;gap:8px;margin-top:15px;font:13px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;color:#38383a}.method{padding:4px 7px;border-radius:6px;background:#e4f5eb;color:var(--green);font:700 11px/1 -apple-system,BlinkMacSystemFont,"SF Pro Text",sans-serif;letter-spacing:.04em}.anchor{margin-top:4px;color:#8e8e93;font-size:12px}.anchor:hover{color:var(--blue)}
|
||
.grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,.92fr);gap:34px;margin-top:23px}.subhead{margin:0 0 9px;font-size:13px;font-weight:650;color:#3a3a3c}.param-table{width:100%;border-collapse:collapse;font-size:13px}.param-table th,.param-table td{padding:10px 8px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}.param-table th{color:var(--muted);font-weight:500}.param-table td:first-child{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:#303033}.required{color:var(--green);font-size:12px}.optional{color:var(--muted);font-size:12px}.code{margin:0;overflow:auto;padding:15px;border-radius:12px;background:var(--code);color:#f5f5f7;font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre}.code .key{color:#82b9ff}.code .number{color:#a8d5a2}.code .string{color:#f5cc88}.note{margin:14px 0 0;padding:11px 12px;border-left:2px solid var(--blue);background:#f4f8fd;color:#59595d;font-size:13px}.note strong{color:#303033}.errors{margin:14px 0 0;padding:0;color:#59595d;font-size:13px;list-style:none}.errors li{position:relative;padding:3px 0 3px 13px}.errors li::before{content:"";position:absolute;top:11px;left:0;width:4px;height:4px;border-radius:50%;background:#ff9f0a}.empty{margin-top:16px;color:var(--muted);font-size:13px}.field-tabs{display:flex;gap:4px;margin:0 0 14px;padding:3px;width:max-content;border-radius:9px;background:#ececf1}.field-tab{appearance:none;border:0;border-radius:7px;padding:7px 10px;background:transparent;color:#6e6e73;font:600 12px/1 -apple-system,BlinkMacSystemFont,"SF Pro Text",sans-serif;cursor:pointer}.field-tab[aria-selected="true"]{background:#fff;color:#1d1d1f;box-shadow:0 1px 3px rgba(0,0,0,.12)}.response-panel{display:none}.response-panel.active{display:block}.response-caption{margin:0 0 9px;color:var(--muted);font-size:12px}.response-table th:nth-child(1){width:31%}.response-table th:nth-child(2){width:17%}.response-table td:nth-child(2){color:#6e6e73;font:12px ui-monospace,SFMono-Regular,Menlo,monospace}.response-table td:nth-child(3){color:#4b4b4f}.tree-field{display:flex;align-items:center;gap:6px;min-height:20px;white-space:nowrap}.tree-field.depth-1{padding-left:14px}.tree-field.depth-2{padding-left:31px}.tree-field.depth-3{padding-left:48px}.tree-branch{width:9px;height:16px;border-left:1px solid #c7c7cc;border-bottom:1px solid #c7c7cc;border-radius:0 0 0 3px}.tree-root{display:inline-flex;align-items:center;gap:5px;font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",sans-serif;font-size:12px;font-weight:650;color:#303033}.tree-root::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--blue)}.tree-node{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:#303033}.tree-kind{display:inline-block;margin-left:5px;padding:1px 5px;border-radius:5px;background:#f0f1f4;color:#6e6e73;font:10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.enum-value{display:inline-block;margin:2px 3px 2px 0;padding:2px 5px;border-radius:5px;background:#f1f6fd;color:#1665b5;font:11px ui-monospace,SFMono-Regular,Menlo,monospace}
|
||
.auth{margin-top:20px;padding:17px 18px;border:1px solid var(--line);border-radius:14px;background:var(--surface)}.auth code{display:block;margin-top:8px;color:#38383a;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.protocol-table{width:100%;margin-top:18px;border-collapse:collapse}.protocol-table th,.protocol-table td{padding:12px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}.protocol-table th{color:var(--muted);font-size:13px;font-weight:500}.protocol-table td:first-child{width:170px;font:12px ui-monospace,SFMono-Regular,Menlo,monospace}.error-table{margin-top:18px}.request-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-top:21px}.request-sample{padding:15px;border:1px solid var(--line);border-radius:14px;background:var(--surface)}.request-sample h3{margin:0 0 6px;font-size:13px;font-weight:650}.request-sample .endpoint{margin:0 0 11px;font-size:11px}.request-sample .code{padding:12px;border-radius:9px;font-size:11px}@media(max-width:680px){.request-grid{grid-template-columns:1fr}.request-sample{padding:13px}}
|
||
@media(max-width:900px){:root{--sidebar:218px}.content{padding:42px 34px 76px}.grid{grid-template-columns:1fr;gap:22px}}
|
||
@media(max-width:680px){body{background:var(--surface)}.layout{display:block}.sidebar{z-index:3;display:flex;align-items:center;gap:0;position:sticky;width:100%;height:auto;padding:0 12px;border-right:0;border-bottom:1px solid var(--line);overflow-x:auto;overflow-y:hidden;white-space:nowrap;background:rgba(255,255,255,.92)}.brand{padding:13px 10px 13px 0}.brand-name{font-size:14px}.brand-subtitle,.nav-title{display:none}.nav-group{display:contents;border:0;padding:0}.nav-link{margin:0;padding:13px 9px;font-size:13px}.nav-link::before{display:none}.external{display:none}.content{padding:31px 20px 64px}.intro{padding-bottom:27px}h1{font-size:31px}.intro p{font-size:15px}.section{padding:31px 0;scroll-margin-top:54px}.section:target{margin:0 -8px;padding-right:8px;padding-left:8px}.section-head{gap:9px}.section h2{font-size:21px}.anchor{display:none}.grid{margin-top:19px}.param-table th,.param-table td{padding:9px 5px}.param-table th:nth-child(2),.param-table td:nth-child(2){width:47px}.base-url{max-width:100%;overflow:auto}.code{font-size:11px}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="layout">
|
||
<aside class="sidebar" aria-label="接口导航">
|
||
<a class="brand" href="#overview"><span class="brand-name">羚牛 · 数据开放平台</span><span class="brand-subtitle">车辆数据 API Reference</span></a>
|
||
<nav>
|
||
<div class="nav-group"><span class="nav-title">开始使用</span><a class="nav-link docs" href="#overview">平台简介</a><a class="nav-link docs" href="#authentication">认证与授权</a><a class="nav-link docs" href="#request-examples">请求体样例</a></div>
|
||
<div class="nav-group"><span class="nav-title">车辆数据</span><a class="nav-link primary" href="#daily-hydrogen">车辆单日用氢量</a><a class="nav-link primary" href="#daily-mileage">车辆单日里程</a><a class="nav-link primary" href="#mileage-range">车辆区间日里程</a><a class="nav-link primary" href="#total-mileage">指定时刻总里程</a><a class="nav-link primary" href="#realtime">实时位置与状态</a></div>
|
||
<div class="nav-group"><span class="nav-title">加氢服务</span><a class="nav-link station" href="#stationary">加氢车辆停留核验</a><a class="nav-link station" href="#stations">加氢站地图点位</a></div>
|
||
<div class="nav-group"><span class="nav-title">通用说明</span><a class="nav-link docs" href="#response-fields">返回字段与枚举</a><a class="nav-link docs" href="#protocols">总里程协议口径</a><a class="nav-link docs" href="#errors">异常与状态码</a></div>
|
||
</nav>
|
||
<a class="external" href="/open-api/swagger/">Swagger 在线调试 <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 3h7v7M13 3 6.5 9.5M12 9.5V13H3V4h3.5"/></svg></a>
|
||
</aside>
|
||
<main class="content">
|
||
<header class="intro" id="overview">
|
||
<h1>接口文档</h1>
|
||
<p>面向合作方开放车辆用氢量、里程、实时状态及加氢车辆停留核验数据。每个接口独立说明请求参数、成功返回与异常情况。</p>
|
||
<span class="base-url">Base URL <code>https://open.d.lnoneos.com</code></span>
|
||
</header>
|
||
|
||
<section class="section" id="authentication"><div class="section-head"><div><h2>认证与授权</h2><p>所有接口均使用平台管理员签发的 32 位 appKey。appKey 有效期及车辆授权期必须完整覆盖查询时间。</p></div><a class="anchor" href="#authentication">#</a></div><div class="auth"><strong>请求头</strong><code>Authorization: Bearer <YOUR_APP_KEY><br>Content-Type: application/json</code></div><div class="note"><strong>授权边界:</strong>不传车牌时,仅返回该 appKey 在查询日期或时间段内有效授权的全部车辆;显式传入的车牌未授权时,接口返回 403。所有接口响应均以两空格缩进的 JSON 返回,便于直接阅读和留存。</div></section>
|
||
|
||
<section class="section" id="request-examples"><div class="section-head"><div><h2>请求体样例</h2><p>所有接口使用 <code>Content-Type: application/json</code>。以下 JSON 可直接复制;未列出的可选字段可省略。</p></div><a class="anchor" href="#request-examples">#</a></div><div class="request-grid"><article class="request-sample"><h3>车辆单日用氢量</h3><div class="endpoint">/vehicles/hydrogen-consumption/query</div><pre class="code">{
|
||
"date": "2026-08-06",
|
||
"plateNumbers": ["浙F06618F"]
|
||
}</pre></article><article class="request-sample"><h3>车辆单日里程</h3><div class="endpoint">/vehicles/mileage/query</div><pre class="code">{
|
||
"date": "2026-08-06",
|
||
"plateNumbers": ["浙F06618F"],
|
||
"protocolPriority": ["GB32960", "MQTT", "JT808"]
|
||
}</pre></article><article class="request-sample"><h3>车辆区间日里程</h3><div class="endpoint">/vehicles/mileage/range/query</div><pre class="code">{
|
||
"startDate": "2026-08-01",
|
||
"endDate": "2026-08-06",
|
||
"pageSize": 100
|
||
}</pre></article><article class="request-sample"><h3>指定时刻总里程</h3><div class="endpoint">/vehicles/total-mileage/query</div><pre class="code">{
|
||
"vin": "LA9GG68L2PBAF4790",
|
||
"time": "2026-08-06 10:30:00",
|
||
"protocol": "GB32960"
|
||
}</pre></article><article class="request-sample"><h3>实时位置与状态</h3><div class="endpoint">/vehicles/realtime/query</div><pre class="code">{
|
||
"plateNumbers": ["浙F06618F"]
|
||
}</pre></article><article class="request-sample"><h3>加氢车辆停留核验</h3><div class="endpoint">/vehicles/stationary/query</div><pre class="code">{
|
||
"startTime": "2026-08-06 10:00:00",
|
||
"endTime": "2026-08-06 12:00:00",
|
||
"longitude": 120.752312,
|
||
"latitude": 30.746281,
|
||
"coordinateSystem": "GCJ02",
|
||
"radiusMeters": 8
|
||
}</pre></article><article class="request-sample"><h3>加氢站地图点位</h3><div class="endpoint">/hydrogen-stations/query</div><pre class="code">{
|
||
"province": "浙江省",
|
||
"city": "嘉兴市",
|
||
"cooperateOnly": true
|
||
}</pre></article></div></section>
|
||
|
||
<section class="section" id="daily-hydrogen"><div class="section-head"><div><h2>车辆单日用氢量</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/hydrogen-consumption/query</div><p>查询车辆单日用氢量,单位 kg。</p></div><a class="anchor" href="#daily-hydrogen">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>date</td><td class="required">是</td><td>日期,格式 yyyy-MM-dd</td></tr><tr><td>plateNumbers</td><td class="optional">否</td><td>车牌数组;省略或 [] 时查询全部授权车辆</td></tr></table></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"code"</span>: <span class="string">"SUCCESS"</span>,<br> <span class="key">"data"</span>: [{<br> <span class="key">"plateNumber"</span>: <span class="string">"浙F06618F"</span>,<br> <span class="key">"hydrogenConsumptionKg"</span>: <span class="number">12.315</span>,<br> <span class="key">"status"</span>: <span class="string">"NORMAL"</span><br> }]<br>}</pre><ul class="errors"><li>400:日期或车牌格式不正确</li><li>401:appKey 无效、停用或过期</li><li>403:指定车辆未授权</li></ul></div></div></section>
|
||
|
||
<section class="section" id="daily-mileage"><div class="section-head"><div><h2>车辆单日里程</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/mileage/query</div><p>返回当日行驶里程、当日累计总里程和实际选用的数据协议,单位 km。</p></div><a class="anchor" href="#daily-mileage">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>date</td><td class="required">是</td><td>日期,格式 yyyy-MM-dd</td></tr><tr><td>plateNumbers</td><td class="optional">否</td><td>省略时查询全部授权车辆</td></tr><tr><td>protocolPriority</td><td class="optional">否</td><td>协议选源顺序,例如 ["GB32960","MQTT","JT808"]</td></tr></table><div class="note"><strong>缺数规则:</strong>若当日没有有效里程,日里程为 0;累计总里程沿用上一个有效统计周期,计算时间也显示该周期时间。</div></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"code"</span>: <span class="string">"SUCCESS"</span>,<br> <span class="key">"data"</span>: [{<br> <span class="key">"dailyMileageKm"</span>: <span class="number">182.437</span>,<br> <span class="key">"totalMileageKm"</span>: <span class="number">12345.679</span>,<br> <span class="key">"sourceProtocol"</span>: <span class="string">"GB32960"</span>,<br> <span class="key">"status"</span>: <span class="string">"NORMAL"</span><br> }]<br>}</pre><ul class="errors"><li>400:日期、车牌或协议参数错误</li><li>403:授权期未覆盖查询日</li><li>无统计:单车以 NO_DATA 返回</li></ul></div></div></section>
|
||
|
||
<section class="section" id="mileage-range"><div class="section-head"><div><h2>车辆区间日里程</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/mileage/range/query</div><p>按车辆、日期分页返回区间日里程,最长查询区间为 366 天。</p></div><a class="anchor" href="#mileage-range">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>startDate / endDate</td><td class="required">是</td><td>日期区间,yyyy-MM-dd</td></tr><tr><td>plateNumbers</td><td class="optional">否</td><td>车牌数组,最多 5000 辆</td></tr><tr><td>protocolPriority</td><td class="optional">否</td><td>协议选源顺序</td></tr><tr><td>pageSize / cursor</td><td class="optional">否</td><td>分页大小及下一页游标</td></tr></table></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"code"</span>: <span class="string">"SUCCESS"</span>,<br> <span class="key">"data"</span>: [{<br> <span class="key">"date"</span>: <span class="string">"2026-08-06"</span>,<br> <span class="key">"dailyMileageKm"</span>: <span class="number">182.437</span>,<br> <span class="key">"totalMileageKm"</span>: <span class="number">12345.679</span><br> }],<br> <span class="key">"nextCursor"</span>: <span class="string">null</span><br>}</pre><ul class="errors"><li>400:区间超限或游标与原参数不一致</li><li>403:授权未完整覆盖查询区间</li></ul></div></div></section>
|
||
|
||
<section class="section" id="total-mileage"><div class="section-head"><div><h2>指定时刻总里程</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/total-mileage/query</div><p>按 VIN 返回不晚于指定时刻的最近一条总里程及实际采集协议。</p></div><a class="anchor" href="#total-mileage">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>vin</td><td class="required">是</td><td>17 位已授权 VIN</td></tr><tr><td>time</td><td class="required">是</td><td>北京时间 yyyy-MM-dd HH:mm:ss</td></tr><tr><td>protocol</td><td class="optional">否</td><td>GB32960、MQTT 或 JT808;省略时按默认顺序选取</td></tr></table></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"code"</span>: <span class="string">"SUCCESS"</span>,<br> <span class="key">"data"</span>: {<br> <span class="key">"totalMileageKm"</span>: <span class="number">12345.678</span>,<br> <span class="key">"protocol"</span>: <span class="string">"GB32960"</span>,<br> <span class="key">"recordTime"</span>: <span class="string">"2026-08-06 10:29:45"</span>,<br> <span class="key">"timeDifferenceSeconds"</span>: <span class="number">15</span><br> }<br>}</pre><ul class="errors"><li>400:VIN、时间或协议不合法</li><li>403:VIN 未授权</li><li>无记录:返回 NO_DATA</li></ul></div></div></section>
|
||
|
||
<section class="section" id="realtime"><div class="section-head"><div><h2>车辆实时位置与状态</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/realtime/query</div><p>返回最新位置、在线状态、速度、总里程、实际协议和记录时间。</p></div><a class="anchor" href="#realtime">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>plateNumbers</td><td class="optional">否</td><td>省略或 [] 时返回全部当前有效授权车辆</td></tr></table></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"data"</span>: [{<br> <span class="key">"vin"</span>: <span class="string">"LA9GG68L2PBAF4790"</span>,<br> <span class="key">"plateNumber"</span>: <span class="string">"浙F06618F"</span>,<br> <span class="key">"sourceProtocol"</span>: <span class="string">"GB32960"</span>,<br> <span class="key">"longitude"</span>: <span class="number">120.75</span>,<br> <span class="key">"latitude"</span>: <span class="number">30.74</span>,<br> <span class="key">"speedKmh"</span>: <span class="number">0</span>,<br> <span class="key">"totalMileageKm"</span>: <span class="number">12345.678</span>,<br> <span class="key">"recordTime"</span>: <span class="string">"2026-08-17 17:40:12"</span>,<br> <span class="key">"timeDifferenceSeconds"</span>: <span class="number">8</span>,<br> <span class="key">"online"</span>: <span class="number">true</span>,<br> <span class="key">"activeToday"</span>: <span class="number">true</span>,<br> <span class="key">"motionStatus"</span>: <span class="string">"idle"</span>,<br> <span class="key">"locationAvailable"</span>: <span class="number">true</span>,<br> <span class="key">"status"</span>: <span class="string">"NORMAL"</span><br> }]<br>}</pre><ul class="errors"><li>400:车牌格式错误</li><li>403:指定车牌未授权</li><li>无实时记录:返回 NO_DATA</li></ul></div></div></section>
|
||
|
||
<section class="section" id="stationary"><div class="section-head"><div><h2>加氢车辆停留核验</h2><div class="endpoint"><span class="method">POST</span>/api/v1/vehicles/stationary/query</div><p>按站点坐标、坐标系、时间段和半径,核验速度接近 0 的车辆停留记录,并按匹配度降序返回。</p></div><a class="anchor" href="#stationary">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>startTime / endTime</td><td class="required">是</td><td>北京时间;查询区间最长 24 小时</td></tr><tr><td>longitude / latitude</td><td class="required">是</td><td>加氢站经纬度;由 coordinateSystem 说明坐标系</td></tr><tr><td>coordinateSystem</td><td class="optional">否</td><td>WGS84(默认)或 GCJ02(高德);GCJ02 自动转换后核验</td></tr><tr><td>radiusMeters</td><td class="optional">否</td><td>核验半径,单位 m;1–100,默认 5</td></tr><tr><td>plateNumbers</td><td class="optional">否</td><td>省略时核验全部有效授权车辆</td></tr></table><div class="note"><strong>匹配规则:</strong>速度 ≤ 3 km/h,至少 2 个样本且停留 ≥ 60 秒;相邻定位点间隔超过 10 分钟时拆分停留区间。</div></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"data"</span>: [{<br> <span class="key">"plateNumber"</span>: <span class="string">"浙F06618F"</span>,<br> <span class="key">"stayStartTime"</span>: <span class="string">"2026-08-06 10:16:02"</span>,<br> <span class="key">"stayEndTime"</span>: <span class="string">"2026-08-06 10:42:18"</span>,<br> <span class="key">"stayDurationSeconds"</span>: <span class="number">1576</span>,<br> <span class="key">"matchScore"</span>: <span class="number">93.842</span><br> }]<br>}</pre><ul class="errors"><li>400:时间、坐标、坐标系或半径不合法</li><li>403:授权期未覆盖整个时间段</li><li>无匹配:data 为空数组</li></ul></div></div></section>
|
||
|
||
<section class="section" id="stations"><div class="section-head"><div><h2>加氢站地图点位</h2><div class="endpoint"><span class="method">POST</span>/api/v1/hydrogen-stations/query</div><p>只读查询有有效坐标的加氢站,可按行政区划和合作属性筛选。</p></div><a class="anchor" href="#stations">#</a></div><div class="grid"><div><h3 class="subhead">请求参数</h3><table class="param-table"><tr><th>字段</th><th>必填</th><th>说明</th></tr><tr><td>province / city</td><td class="optional">否</td><td>行政区划筛选</td></tr><tr><td>cooperateOnly</td><td class="optional">否</td><td>true 仅合作站;false 仅外部站</td></tr></table></div><div><h3 class="subhead">成功返回 · 200</h3><pre class="code">{<br> <span class="key">"data"</span>: [{<br> <span class="key">"id"</span>: <span class="string">"1"</span>,<br> <span class="key">"name"</span>: <span class="string">"示例加氢站"</span>,<br> <span class="key">"longitude"</span>: <span class="number">120.752312</span>,<br> <span class="key">"latitude"</span>: <span class="number">30.746281</span>,<br> <span class="key">"cooperative"</span>: <span class="number">true</span><br> }]<br>}</pre><ul class="errors"><li>400:行政区划参数过长</li><li>401:appKey 无效</li><li>无符合站点:data 为空数组</li></ul></div></div></section>
|
||
|
||
<section class="section" id="response-fields"><div class="section-head"><div><h2>返回字段与枚举说明</h2><p>所有成功响应外层固定包含 code、message、data 和 traceId;以下为 data 内的字段。无数据时按对应接口返回 null、NO_DATA 或空数组。</p></div><a class="anchor" href="#response-fields">#</a></div><h3 class="subhead" style="margin-top:22px">通用响应与状态</h3><table class="protocol-table"><tr><th>字段/枚举</th><th>说明</th></tr><tr><td>code = SUCCESS</td><td>请求已成功处理。业务数据是否存在由每条数据的 status 判断。</td></tr><tr><td>message</td><td>成功时固定为 success。</td></tr><tr><td>traceId</td><td>本次请求唯一追踪标识;异常排查时请完整提供。</td></tr><tr><td>status = NORMAL</td><td>存在可用数据,相关数值、协议和时间字段有效。</td></tr><tr><td>status = NO_DATA</td><td>在授权范围内未找到可用数据;可选数值、位置、时间字段为 null 或省略。</td></tr><tr><td>status = DATA_ANOMALY</td><td>检测到数据异常,当前不返回可能错误的里程;dataQuality 给出原因。</td></tr><tr><td>dataQuality = TOTAL_MILEAGE_ROLLBACK</td><td>终端累计里程明显回退,已阻止其作为正常累计里程返回。</td></tr></table><h3 class="subhead" style="margin-top:28px">车辆单日用氢量</h3><table class="protocol-table"><tr><th>字段</th><th>说明</th></tr><tr><td>plateNumber / date</td><td>车牌与查询自然日(Asia/Shanghai)。</td></tr><tr><td>hydrogenConsumptionKg</td><td>当日用氢量,单位 kg;无有效数据时为 null。</td></tr><tr><td>status</td><td>NORMAL 表示已计算;NO_DATA 表示无可用统计。</td></tr></table><h3 class="subhead" style="margin-top:28px">车辆单日里程与区间日里程</h3><table class="protocol-table"><tr><th>字段</th><th>说明</th></tr><tr><td>vin / plateNumber / date</td><td>车辆唯一 VIN、车牌和统计自然日。</td></tr><tr><td>dailyMileageKm</td><td>当日行驶里程,单位 km。缺少当日记录且可前向补齐时为 0。</td></tr><tr><td>totalMileageKm</td><td>所选协议的日末累计总里程,单位 km;不会用 GPS 日里程估算值替代。</td></tr><tr><td>sourceProtocol</td><td>实际采用的协议:GB32960、MQTT 或 JT808。</td></tr><tr><td>dataTime</td><td>实际采用的最后一条车辆源数据时间。</td></tr><tr><td>updatedAt</td><td>该统计周期的计算时间;前向补齐时保持上一有效统计周期时间。</td></tr><tr><td>snapshotId / nextCursor</td><td>仅区间接口返回;snapshotId 固定本次分页车辆范围,nextCursor 为下一页游标,最后一页为 null。</td></tr></table><h3 class="subhead" style="margin-top:28px">指定时刻总里程</h3><table class="protocol-table"><tr><th>字段</th><th>说明</th></tr><tr><td>vin / queryTime</td><td>查询车辆 VIN 与请求的北京时间。</td></tr><tr><td>totalMileageKm</td><td>不晚于请求时间的最近一条累计总里程,单位 km。</td></tr><tr><td>protocol / protocolInput</td><td>protocol 为实际命中协议;protocolInput 为请求显式传入的协议,未传则省略。</td></tr><tr><td>recordTime / timeDifferenceSeconds</td><td>实际命中记录时间,以及请求时间与记录时间的差值,单位秒。</td></tr><tr><td>mileageMeaning</td><td>该协议累计里程的业务口径;JT808 为定位终端/GPS侧累计值。</td></tr></table><h3 class="subhead" style="margin-top:28px">车辆实时位置与状态</h3><table class="protocol-table"><tr><th>字段/枚举</th><th>说明</th></tr><tr><td>sourceProtocol</td><td>本条位置、速度、累计里程和记录时间实际采用的协议:GB32960、MQTT 或 JT808。</td></tr><tr><td>longitude / latitude</td><td>最新有效经纬度;无有效位置时为 null,locationAvailable 为 false。</td></tr><tr><td>speedKmh / totalMileageKm</td><td>所选来源的瞬时速度(km/h)和累计总里程(km)。</td></tr><tr><td>recordTime / timeDifferenceSeconds</td><td>所选来源的记录时间,以及与当前查询时间的差值,单位秒。</td></tr><tr><td>online</td><td>true:任一协议最近 60 秒内上报;false:没有任一协议满足该实时阈值。</td></tr><tr><td>activeToday</td><td>true:任一协议在当前自然日曾上报;不等同于实时 online。</td></tr><tr><td>motionStatus = driving</td><td>在线且所选来源速度大于 3 km/h。</td></tr><tr><td>motionStatus = idle</td><td>在线且所选来源速度不大于 3 km/h。</td></tr><tr><td>motionStatus = offline</td><td>当前不在线,或没有实时记录。</td></tr><tr><td>protocol</td><td>旧版兼容字段;新接入请使用 sourceProtocol。</td></tr></table><h3 class="subhead" style="margin-top:28px">加氢车辆停留核验</h3><table class="protocol-table"><tr><th>字段</th><th>说明</th></tr><tr><td>stayStartTime / stayEndTime</td><td>满足核验条件的连续停留开始、结束时间。</td></tr><tr><td>stayDurationSeconds / stayDurationMinutes</td><td>停留时长,分别以秒、分钟表示。</td></tr><tr><td>matchScore</td><td>0–100;位置越接近、速度越低、停留越久、样本越充分,分数越高。</td></tr><tr><td>averageDistanceMeters / maxDistanceMeters</td><td>定位点相对输入站点坐标的平均/最大距离,单位 m。</td></tr><tr><td>averageSpeedKmh / maxSpeedKmh / matchedSamples</td><td>核验区间内速度统计与匹配定位样本数。</td></tr><tr><td>sourceProtocols</td><td>本停留片段采用过的协议数组,枚举值为 GB32960、MQTT、JT808。</td></tr></table><h3 class="subhead" style="margin-top:28px">加氢站地图点位</h3><table class="protocol-table"><tr><th>字段</th><th>说明</th></tr><tr><td>id / name / shortName</td><td>站点唯一标识、标准名称和简称;id 为字符串以避免 JavaScript 精度丢失。</td></tr><tr><td>address / province / city / district</td><td>站点地址及行政区划。</td></tr><tr><td>longitude / latitude</td><td>站点坐标。</td></tr><tr><td>cooperative</td><td>true:合作站(内部站或已导入合作名录);false:外部站。</td></tr></table></section>
|
||
|
||
<section class="section" id="protocols"><div class="section-head"><div><h2>总里程协议口径</h2><p>未指定 protocol 时,按 GB32960 > MQTT > JT808 选择第一个有数据的协议;不会跨协议拼接里程。</p></div><a class="anchor" href="#protocols">#</a></div><table class="protocol-table"><tr><th>规范值</th><th>总里程含义</th></tr><tr><td>GB32960</td><td>车辆仪表盘累计总里程,对应 GB/T 32960 整车数据累计里程。</td></tr><tr><td>MQTT</td><td>车辆仪表盘或车端控制器累计总里程,由 MQTT 平台上报。</td></tr><tr><td>JT808</td><td>定位终端累计里程,由 GPS/终端侧计算,不等同于车辆仪表盘里程。</td></tr></table></section>
|
||
|
||
<section class="section" id="errors"><div class="section-head"><div><h2>异常与状态码</h2><p>所有响应均包含 <code>code</code>、<code>message</code> 和 <code>traceId</code>;请在工单中提供 traceId 以便排查。</p></div><a class="anchor" href="#errors">#</a></div><table class="protocol-table error-table"><tr><th>HTTP</th><th>code</th><th>说明</th></tr><tr><td>200</td><td>SUCCESS</td><td>查询成功;无统计数据时,数据行的 status 为 NO_DATA。</td></tr><tr><td>400</td><td>INVALID_REQUEST</td><td>请求格式、数量、日期、时间、坐标或协议不正确。</td></tr><tr><td>401</td><td>UNAUTHORIZED</td><td>appKey 不存在、停用或已过期。</td></tr><tr><td>403</td><td>FORBIDDEN</td><td>车辆或 appKey 授权期未覆盖请求时间。</td></tr><tr><td>500</td><td>INTERNAL_ERROR</td><td>服务内部异常;请提供 traceId。</td></tr></table></section>
|
||
</main>
|
||
</div>
|
||
<script>
|
||
(() => {
|
||
const common = [
|
||
["code", "string", "固定为 SUCCESS,表示 HTTP 请求处理成功;请结合 data 内每条 status 判断是否有业务数据。"],
|
||
["message", "string", "成功时固定为 success。"],
|
||
["traceId", "string", "本次请求的唯一追踪标识;出现问题时请完整提供给羚牛技术支持。"]
|
||
];
|
||
const fields = {
|
||
"daily-hydrogen": [
|
||
["data[]", "array", "按请求车牌顺序返回的车辆数据数组。"],
|
||
["data[].plateNumber", "string", "车辆车牌号。"],
|
||
["data[].date", "date", "查询自然日,格式 yyyy-MM-dd,时区 Asia/Shanghai。"],
|
||
["data[].hydrogenConsumptionKg", "number | null", "当日用氢量,单位 kg;无有效统计时为 null。"],
|
||
["data[].status", "enum", "<span class='enum-value'>NORMAL</span> 已计算出有效用氢量;<span class='enum-value'>NO_DATA</span> 无可用统计。"]
|
||
],
|
||
"daily-mileage": [
|
||
["data[]", "array", "按请求车牌顺序返回的车辆数据数组。"],
|
||
["data[].vin", "string", "车辆唯一 VIN。"], ["data[].plateNumber", "string", "车辆车牌号。"], ["data[].date", "date", "查询自然日,yyyy-MM-dd,Asia/Shanghai。"],
|
||
["data[].dailyMileageKm", "number | null", "当日行驶里程,单位 km;若当日无记录但存在此前有效累计里程,则返回 0。"],
|
||
["data[].totalMileageKm", "number | null", "日末累计总里程,单位 km;仅采用终端累计里程,不以 GPS 日里程估算替代。"],
|
||
["data[].sourceProtocol", "enum | null", "<span class='enum-value'>GB32960</span> GB/T 32960 车辆仪表累计里程;<span class='enum-value'>MQTT</span> 车端/MQTT 平台累计里程;<span class='enum-value'>JT808</span> 定位终端/GPS侧累计里程。"],
|
||
["data[].dataTime", "datetime | null", "本条统计实际采用的最后一条车辆源数据时间。"], ["data[].updatedAt", "datetime | null", "本行统计计算时间;前向补齐时为上一个有效统计周期的计算时间。"],
|
||
["data[].status", "enum", "<span class='enum-value'>NORMAL</span> 有效;<span class='enum-value'>NO_DATA</span> 无数据;<span class='enum-value'>DATA_ANOMALY</span> 发现异常,里程不返回。"],
|
||
["data[].dataQuality", "enum | null", "仅 DATA_ANOMALY 时返回。<span class='enum-value'>TOTAL_MILEAGE_ROLLBACK</span> 表示终端累计里程明显回退,已拦截。"]
|
||
],
|
||
"mileage-range": [
|
||
["data[]", "array", "当前页的车辆×日期数据,按请求区间与授权车辆快照排序。单条字段与“车辆单日里程”完全一致。"],
|
||
["data[].vin / plateNumber / date", "string / date", "车辆 VIN、车牌和该行统计自然日。"], ["data[].dailyMileageKm", "number | null", "当日里程,单位 km。"], ["data[].totalMileageKm", "number | null", "该日累计总里程,单位 km。"],
|
||
["data[].sourceProtocol", "enum | null", "<span class='enum-value'>GB32960</span> / <span class='enum-value'>MQTT</span> / <span class='enum-value'>JT808</span>;含义见单日里程接口。"],
|
||
["data[].dataTime / updatedAt", "datetime | null", "采用源数据时间 / 统计计算时间。"], ["data[].status / dataQuality", "enum | null", "NORMAL、NO_DATA、DATA_ANOMALY;异常原因目前为 TOTAL_MILEAGE_ROLLBACK。"],
|
||
["snapshotId", "string", "本次分页授权车辆快照标识;后续翻页必须保持原参数并继续使用。"], ["nextCursor", "string | null", "下一页游标;为 null 表示已到最后一页。"]
|
||
],
|
||
"total-mileage": [
|
||
["data.vin", "string", "查询车辆 VIN。"], ["data.queryTime", "datetime", "请求指定的北京时间。"], ["data.totalMileageKm", "number | null", "不晚于 queryTime 的最近一条累计总里程,单位 km;无记录时为 null。"],
|
||
["data.protocol", "enum | null", "实际命中协议。<span class='enum-value'>GB32960</span> 仪表累计;<span class='enum-value'>MQTT</span> 车端累计;<span class='enum-value'>JT808</span> 定位/GPS累计。"],
|
||
["data.protocolInput", "string | null", "请求中传入的协议原值;未指定时为 null/省略。"], ["data.mileageMeaning", "string | null", "当前 protocol 的累计里程业务口径说明。"],
|
||
["data.recordTime", "datetime | null", "实际命中的源数据记录时间,北京时间。"], ["data.timeDifferenceSeconds", "integer | null", "queryTime 减 recordTime 的秒数。"],
|
||
["data.selectionPolicy", "string", "未指定协议时使用的默认选源顺序。"], ["data.status", "enum", "<span class='enum-value'>NORMAL</span> 找到记录;<span class='enum-value'>NO_DATA</span> 未找到不晚于请求时间的记录。"]
|
||
],
|
||
"realtime": [
|
||
["data[]", "array", "按请求车牌顺序返回;省略车牌时返回当前授权范围内全部车辆。"], ["data[].vin / plateNumber", "string", "车辆唯一 VIN / 车牌。"],
|
||
["data[].protocol", "enum | null", "本条位置、速度、累计里程和记录时间实际采用的唯一协议字段。<span class='enum-value'>GB32960</span> 车辆协议;<span class='enum-value'>MQTT</span> MQTT 车端来源;<span class='enum-value'>JT808</span> 定位终端来源。"],
|
||
["data[].longitude / latitude", "number | null", "所选来源的最新有效经度/纬度;无位置时为 null。"], ["data[].speedKmh", "number | null", "所选来源瞬时速度,单位 km/h。"], ["data[].socPercent", "number", "所选来源的动力电池荷电状态,单位 %;仅在采集值为 0–100 时返回,无值或无效值时字段省略。"], ["data[].totalMileageKm", "number | null", "所选来源累计总里程,单位 km。"],
|
||
["data[].recordTime", "datetime | null", "所选来源实际记录时间,北京时间。"], ["data[].timeDifferenceSeconds", "integer | null", "当前查询时间减 recordTime,单位秒。"],
|
||
["data[].online", "boolean", "true:任一采集协议在最近 60 秒内上报;false:没有协议满足实时阈值。"], ["data[].activeToday", "boolean", "true:任一采集协议在当前自然日曾上报;它不等同于 online。"],
|
||
["data[].motionStatus", "enum", "<span class='enum-value'>driving</span> 在线且所选速度 > 3 km/h;<span class='enum-value'>idle</span> 在线且速度 ≤ 3 km/h;<span class='enum-value'>offline</span> 当前不在线或无实时记录。"],
|
||
["data[].locationAvailable", "boolean", "true:longitude 与 latitude 有效;false:当前无有效位置。"], ["data[].status", "enum", "<span class='enum-value'>NORMAL</span> 找到实时记录;<span class='enum-value'>NO_DATA</span> 无实时记录。"]
|
||
],
|
||
"stationary": [
|
||
["data[]", "array", "满足站点停留匹配条件的车辆片段;无匹配时为空数组。"], ["data[].vin / plateNumber", "string", "车辆唯一 VIN / 车牌。"],
|
||
["data[].stayStartTime / stayEndTime", "datetime", "连续停留片段的起止定位时间,北京时间。"], ["data[].stayDurationSeconds / stayDurationMinutes", "integer / number", "停留时长,分别以秒/分钟表示。"],
|
||
["data[].matchScore", "number", "0–100;位置越接近、速度越低、停留越久、样本越充分,分数越高。"], ["data[].averageDistanceMeters / maxDistanceMeters", "number", "定位点相对输入站点坐标的平均/最大距离,单位 m。"],
|
||
["data[].averageSpeedKmh / maxSpeedKmh", "number", "停留片段内平均/最大速度,单位 km/h。"], ["data[].matchedSamples", "integer", "用于该停留片段的定位样本数,至少为 2。"],
|
||
["data[].sourceProtocols", "array<enum>", "片段中实际采用过的协议数组:GB32960、MQTT、JT808。"]
|
||
],
|
||
"stations": [
|
||
["data[]", "array", "符合行政区划与合作属性筛选条件的站点数组;无符合项时为空数组。"], ["data[].id", "string", "站点 ID 使用字符串,避免 JavaScript 大整数精度丢失。"], ["data[].name / shortName", "string", "站点标准名称 / 简称。"],
|
||
["data[].address", "string", "站点地址。"], ["data[].longitude / latitude", "number", "站点经纬度。"], ["data[].province / city / district", "string", "站点省、市、区县行政区划。"],
|
||
["data[].cooperative", "boolean", "true:合作站(内部站或已导入合作名录);false:外部站。"]
|
||
]
|
||
};
|
||
const sectionIds = Object.keys(fields);
|
||
const esc = value => String(value).replace(/[&<>\"]/g, char => ({"&":"&","<":"<",">":">","\"":"""}[char]));
|
||
const expandFields = rows => rows.flatMap(([path, type, description]) => {
|
||
if (path === "data[]") return [[path, type, description]];
|
||
const prefix = path.startsWith("data[].") ? "data[]." : (path.startsWith("data.") ? "data." : "");
|
||
const names = path.slice(prefix.length).split(" / ");
|
||
const types = type.split(" / ");
|
||
return names.map((name, index) => [prefix + name, types[index] || type, description]);
|
||
});
|
||
const treeCell = (depth, name, kind, root) => {
|
||
const branch = root ? "" : "<span class='tree-branch' aria-hidden='true'></span>";
|
||
const label = root ? "<span class='tree-root'>" + esc(name) + "</span>" : "<span class='tree-node'>" + esc(name) + "</span>";
|
||
return "<div class='tree-field depth-" + depth + "'>" + branch + label + (kind ? "<span class='tree-kind'>" + esc(kind) + "</span>" : "") + "</div>";
|
||
};
|
||
const renderResponseTree = rows => {
|
||
const expanded = expandFields(rows);
|
||
const dataArray = expanded.find(row => row[0] === "data[]");
|
||
const dataObject = expanded.some(row => row[0].startsWith("data."));
|
||
const regular = expanded.filter(row => row[0] !== "data[]");
|
||
const outer = regular.filter(row => !row[0].startsWith("data.") && !row[0].startsWith("data[]."));
|
||
const nested = regular.filter(row => row[0].startsWith("data.") || row[0].startsWith("data[]."));
|
||
let html = "<tr class='tree-root-row'><td>" + treeCell(0, "响应对象", "object", true) + "</td><td>object</td><td>本接口成功响应的 JSON 根对象。</td></tr>";
|
||
html += common.map(row => "<tr><td>" + treeCell(1, row[0], "", false) + "</td><td>" + esc(row[1]) + "</td><td>" + row[2] + "</td></tr>").join("");
|
||
if (dataArray) {
|
||
html += "<tr><td>" + treeCell(1, "data", "array", false) + "</td><td>array</td><td>" + dataArray[2] + "</td></tr>";
|
||
html += "<tr><td>" + treeCell(2, "[]", "object", false) + "</td><td>object</td><td>data 数组中的一条车辆/站点数据。</td></tr>";
|
||
} else if (dataObject) {
|
||
html += "<tr><td>" + treeCell(1, "data", "object", false) + "</td><td>object</td><td>本次查询对应的一条业务数据。</td></tr>";
|
||
}
|
||
html += nested.map(row => {
|
||
const name = row[0].replace(/^data(?:\[\])?\./, "");
|
||
return "<tr><td>" + treeCell(dataArray ? 3 : 2, name, "", false) + "</td><td>" + esc(row[1]) + "</td><td>" + row[2] + "</td></tr>";
|
||
}).join("");
|
||
html += outer.map(row => "<tr><td>" + treeCell(1, row[0], "", false) + "</td><td>" + esc(row[1]) + "</td><td>" + row[2] + "</td></tr>").join("");
|
||
return html;
|
||
};
|
||
sectionIds.forEach(id => {
|
||
const section = document.getElementById(id);
|
||
const left = section && section.querySelector(".grid > div:first-child");
|
||
if (!left) return;
|
||
const requestTitle = left.querySelector(".subhead");
|
||
const requestTable = left.querySelector("table");
|
||
if (!requestTitle || !requestTable) return;
|
||
requestTitle.remove();
|
||
const tabs = document.createElement("div"); tabs.className = "field-tabs";
|
||
const requestButton = document.createElement("button"); requestButton.className = "field-tab"; requestButton.type = "button"; requestButton.textContent = "请求参数"; requestButton.setAttribute("aria-selected", "true");
|
||
const responseButton = document.createElement("button"); responseButton.className = "field-tab"; responseButton.type = "button"; responseButton.textContent = "返回字段"; responseButton.setAttribute("aria-selected", "false");
|
||
tabs.append(requestButton, responseButton);
|
||
const requestPanel = document.createElement("div"); requestPanel.className = "request-panel"; requestPanel.append(requestTitle, requestTable);
|
||
const responsePanel = document.createElement("div"); responsePanel.className = "response-panel";
|
||
responsePanel.innerHTML = "<h3 class='subhead'>返回字段</h3><p class='response-caption'>按响应 JSON 的对象层级展示;数组元素以 <code>[]</code> 标记,枚举与空值规则已逐项说明。</p><table class='param-table response-table'><tr><th>响应结构</th><th>类型</th><th>说明/枚举</th></tr>" + renderResponseTree(fields[id]) + "</table>";
|
||
left.replaceChildren(tabs, requestPanel, responsePanel);
|
||
requestButton.addEventListener("click", () => { requestButton.setAttribute("aria-selected", "true"); responseButton.setAttribute("aria-selected", "false"); requestPanel.style.display = "block"; responsePanel.classList.remove("active"); });
|
||
responseButton.addEventListener("click", () => { responseButton.setAttribute("aria-selected", "true"); requestButton.setAttribute("aria-selected", "false"); requestPanel.style.display = "none"; responsePanel.classList.add("active"); });
|
||
});
|
||
const realtimeSample = document.querySelector("#realtime .code");
|
||
if (realtimeSample) realtimeSample.innerHTML = realtimeSample.innerHTML.replace("sourceProtocol", "protocol").replace('<span class="key">"speedKmh"</span>:', '<span class="key">"socPercent"</span>: <span class="number">78.5</span>,<br> <span class="key">"speedKmh"</span>:');
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|