263 lines
14 KiB
HTML
263 lines
14 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||
<title>羚牛氢能 - 车辆网络 | Lingniu H2 Executive Cockpit</title>
|
||
<!-- Google Fonts: Inter & JetBrains Mono -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;600;700;800&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="styles.css?v=20260812113000">
|
||
|
||
<!-- 高德地图 (AutoNavi AMap) Web JS API v2.0 Configuration -->
|
||
<script type="text/javascript">
|
||
window._AMapSecurityConfig = {
|
||
securityJsCode: '0b54a41143bec162788d01deba851340',
|
||
}
|
||
</script>
|
||
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=1868920ac8ff6b6f88dbe9fa2609c183&plugin=AMap.Scale,AMap.ToolBar,AMap.Marker"></script>
|
||
</head>
|
||
<body class="theme-white">
|
||
|
||
<!-- APPLE LIQUID GLASS EXECUTIVE COCKPIT WRAPPER -->
|
||
<div class="liquid-cockpit-wrapper">
|
||
|
||
<!-- 1. TOP FLOATING NAVIGATION BAR -->
|
||
<header class="liquid-header floating-glass">
|
||
<div class="header-left">
|
||
<div class="brand-block" title="羚牛氢能 Lingniu Link">
|
||
<!-- Official Lingniu Hydrogen Logo (logo_light.svg) -->
|
||
<div class="brand-logo-switcher">
|
||
<img class="brand-logo-svg" id="brandLogo" src="logo_light.svg" width="150" height="36" alt="羚牛氢能">
|
||
<div class="brand-logo-en" id="brandLogoEnglish" hidden aria-label="Lingniu Hydrogen Mobility">
|
||
<span class="brand-mark-crop"><img src="logo_light.svg" alt=""></span>
|
||
<img src="logo_en.svg?v=20260804045500" alt="Lingniu Hydrogen Mobility">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="brand-divider"></div>
|
||
<div class="cockpit-title-wrap">
|
||
<h1 class="cockpit-title" id="dashboardTitle" data-i18n="vehicleModeTitle">车辆网络</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Top Three Clean Operational KPI Capsules -->
|
||
<div class="header-kpi-group">
|
||
<div class="kpi-glass-capsule">
|
||
<span class="capsule-lbl" id="kpiTotalLabel" data-i18n="kpiTotalFleet">车辆总数</span>
|
||
<span class="capsule-val" id="kpiFleetTotal">-- <small data-i18n="unitVehicles">辆</small></span>
|
||
</div>
|
||
<div class="kpi-glass-capsule primary-capsule">
|
||
<span class="capsule-lbl" id="kpiActiveLabel" data-i18n="kpiOnlineFleet">当前在线运行</span>
|
||
<span class="capsule-val" id="kpiFleetOnline">-- <small data-i18n-append="onlinePct">辆</small></span>
|
||
</div>
|
||
<div class="kpi-glass-capsule">
|
||
<span class="capsule-lbl" id="kpiActivityLabel" data-i18n="kpiDailyMileage">今日运营里程</span>
|
||
<span class="capsule-val" id="kpiDailyDist">-- <small>km</small></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Header Controls: Mode Switcher, Theme Switcher & Language Switcher -->
|
||
<div class="header-controls">
|
||
<div class="glass-segmented-control">
|
||
<button class="segment-btn active" id="btnModeStation" onclick="switchMode('station')" data-i18n="btnStation">加氢站</button>
|
||
<button class="segment-btn is-locked" id="btnModeVehicle" onclick="switchMode('vehicle')" data-i18n="btnVehicle">车辆</button>
|
||
</div>
|
||
|
||
<!-- Bilingual ZH / EN Switcher -->
|
||
<div class="glass-segmented-control lang-switcher-bw">
|
||
<button class="segment-btn lang-zh-btn active" onclick="setLanguage('zh')">中</button>
|
||
<button class="segment-btn lang-en-btn" onclick="setLanguage('en')">EN</button>
|
||
</div>
|
||
|
||
<!-- Professional Vector SVG Theme Switcher (DEFAULT: LIGHT MODE) -->
|
||
<div class="theme-switcher-bw">
|
||
<button class="bw-btn theme-dark-btn" title="深色模式 (Dark Mode)" onclick="setTheme('theme-dark')">
|
||
<svg class="bw-svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||
</svg>
|
||
<span data-i18n="themeDark">深色</span>
|
||
</button>
|
||
<button class="bw-btn theme-white-btn active" title="浅色模式 (Light Mode)" onclick="setTheme('theme-white')">
|
||
<svg class="bw-svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
<span data-i18n="themeLight">浅色</span>
|
||
</button>
|
||
</div>
|
||
|
||
<button class="access-trigger" id="accessTrigger" type="button" onclick="toggleOperationsAccess()" data-i18n="authEntry">运营授权</button>
|
||
|
||
<div class="time-widget" id="clockTime">19:04:00</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- 2. MAIN BODY (CENTER MAP CANVAS + RIGHT SIDEBAR) -->
|
||
<main class="cockpit-main-grid">
|
||
|
||
<!-- SPATIAL AMAP 3D CANVAS LAYER -->
|
||
<section class="map-spatial-container floating-glass">
|
||
|
||
<!-- Map Floating Status Pill -->
|
||
<div class="map-top-bar">
|
||
<div class="status-glass-pill">
|
||
<span class="pulse-ring"></span>
|
||
<span id="mapStatusText">正在同步开放平台数据…</span>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="map-explore-toolbar" aria-label="地图筛选与定位">
|
||
<button class="locate-btn" id="locateDeviceBtn" type="button" onclick="locateDevice()" aria-label="定位到我的位置" title="定位到我的位置">
|
||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||
<circle cx="12" cy="12" r="3"></circle>
|
||
<path d="M12 2v3M12 19v3M2 12h3M19 12h3"></path>
|
||
<circle cx="12" cy="12" r="8"></circle>
|
||
</svg>
|
||
<span id="locateDeviceLabel" data-i18n="btnLocate">定位</span>
|
||
</button>
|
||
|
||
<div class="explore-search-shell">
|
||
<label class="entity-search-field" for="entitySearch">
|
||
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"></circle><path d="m20 20-3.6-3.6"></path></svg>
|
||
<input id="entitySearch" type="search" autocomplete="off" placeholder="搜索位置、站点、车牌或 VIN" aria-label="搜索位置、站点、车牌或 VIN" oninput="handleExploreInput(this.value)" onfocus="openExploreSuggestions()" onkeydown="handleExploreSearchKeydown(event)">
|
||
<button class="search-clear-btn" id="searchClearBtn" type="button" onclick="clearNameFilter()" aria-label="清除名称筛选" hidden>×</button>
|
||
</label>
|
||
<div class="explore-suggestions" id="exploreSuggestions" role="listbox" aria-label="搜索建议" hidden></div>
|
||
</div>
|
||
|
||
<div class="filter-chip-rail" id="filterChipRail" aria-label="当前筛选" hidden></div>
|
||
<span class="filter-result-meta" id="filterResultMeta" aria-live="polite">全部 0</span>
|
||
<span class="location-feedback" id="locationFeedback" role="status" hidden></span>
|
||
</div>
|
||
|
||
<!-- AMap 3D Canvas -->
|
||
<div class="amap-canvas-box">
|
||
<div id="amapContainer"></div>
|
||
|
||
<article class="map-detail-card" id="mapDetailCard" aria-live="polite" hidden>
|
||
<div class="detail-card-accent" id="detailCardAccent"></div>
|
||
<div class="detail-card-header">
|
||
<div class="detail-title-wrap">
|
||
<span class="detail-type-pill" id="detailTypePill">车辆</span>
|
||
<h2 id="detailTitle">—</h2>
|
||
<p id="detailSubtitle"></p>
|
||
</div>
|
||
<div class="detail-card-actions">
|
||
<button class="detail-navigate-btn" id="detailNavigateBtn" type="button" onclick="navigateToSelectedEntity()" aria-label="导航" title="导航" hidden>
|
||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20.7 3.3 14.4 20.1a1.2 1.2 0 0 1-2.2.1l-2.6-5.8-5.8-2.6a1.2 1.2 0 0 1 .1-2.2l16.8-6.3Z"></path><path d="m9.5 14.5 4.9-4.9"></path></svg>
|
||
</button>
|
||
<button class="detail-close-btn" type="button" onclick="closeEntityDetails()" aria-label="关闭详情">×</button>
|
||
</div>
|
||
</div>
|
||
<dl class="detail-grid" id="detailGrid"></dl>
|
||
<button class="detail-expand-btn" id="detailExpandBtn" type="button" onclick="toggleEntityDetails()" hidden>展开详情</button>
|
||
</article>
|
||
|
||
<!-- Bottom Right Floating Controls -->
|
||
<div class="map-action-controls">
|
||
<button class="glass-btn" onclick="resetMapView()" data-i18n="btnResetView">复位视角</button>
|
||
<button class="glass-btn" onclick="togglePitchView()" data-i18n="btn3dView">3D/2D 视角</button>
|
||
<button class="glass-btn" id="filterBtn" onclick="clearProvinceFilter()" data-i18n="btnNationalView">全国视图</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Map Footer Bar -->
|
||
<div class="map-bottom-info">
|
||
<span id="mapFooterGis" data-i18n="mapFooterGis">高质感地图引擎: 羚牛氢能GIS (AMap 3D Engine)</span>
|
||
<span id="mapFooterStatus" data-i18n="mapFooterStatus">系统状态: 稳定连接 (AES-256)</span>
|
||
<span id="selectedRegionHint" data-i18n="hintNational">视角: 全国运营态势</span>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- RIGHT SIDEBAR (2 LIQUID GLASS CARDS) -->
|
||
<aside class="sidebar-operations">
|
||
|
||
<!-- Card 1: vehicles show total / driving / idle; offline is supporting information -->
|
||
<div class="glass-panel sidebar-card">
|
||
<div class="panel-header">
|
||
<span class="panel-title" id="panelStatusTitle">车辆运营状态分布</span>
|
||
<span class="panel-tag">STATUS</span>
|
||
</div>
|
||
|
||
<div class="status-glass-grid3">
|
||
<div class="glass-cell cell-running">
|
||
<div class="cell-num" id="statusValue1">-- <small data-i18n="unitVehicles">辆</small></div>
|
||
<div class="cell-label"><span class="status-dot dot-mint"></span> <span id="statusLabel1" data-i18n="statusRunning">运行中</span> <span id="statusPct1"></span></div>
|
||
</div>
|
||
<div class="glass-cell cell-stopped">
|
||
<div class="cell-num" id="statusValue2">-- <small data-i18n="unitVehicles">辆</small></div>
|
||
<div class="cell-label"><span class="status-dot dot-blue"></span> <span id="statusLabel2" data-i18n="statusStopped">静止中</span> <span id="statusPct2"></span></div>
|
||
</div>
|
||
<div class="glass-cell cell-offline">
|
||
<div class="cell-num" id="statusValue3">-- <small data-i18n="unitVehicles">辆</small></div>
|
||
<div class="cell-label"><span class="status-dot dot-sub"></span> <span id="statusLabel3" data-i18n="statusOffline">离线</span> <span id="statusPct3"></span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Apple Style Segmented Progress Track -->
|
||
<div class="liquid-progress-bar">
|
||
<div class="seg seg-running" style="width: 52.9%;"></div>
|
||
<div class="seg seg-stopped" style="width: 30.4%;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Card 2: 重点区域 TOP 排名 (Liquid Glass Ranking List) -->
|
||
<div class="glass-panel sidebar-card flex-fill-auto">
|
||
<div class="panel-header">
|
||
<div class="panel-heading-stack">
|
||
<span class="panel-title" id="panelRankTitle">车辆累计里程 TOP 排名</span>
|
||
<span class="viewport-meta" id="rankViewportMeta" hidden></span>
|
||
</div>
|
||
<div class="glass-tab-control">
|
||
<button class="gtab active" id="rankPrimaryTab" onclick="switchRankTab('primary')">按数量</button>
|
||
<button class="gtab" id="rankSecondaryTab" onclick="switchRankTab('secondary')">按里程</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="liquid-ranking-list" id="rankingListBox">
|
||
<!-- Dynamic Ranking Rows -->
|
||
</div>
|
||
</div>
|
||
|
||
</aside>
|
||
|
||
</main>
|
||
|
||
</div>
|
||
|
||
<dialog class="access-dialog" id="accessDialog" aria-labelledby="accessDialogTitle">
|
||
<form class="access-dialog-card" method="dialog" onsubmit="event.preventDefault(); authorizeOperationsAccess();">
|
||
<div class="access-dialog-icon" aria-hidden="true">⌁</div>
|
||
<div class="access-dialog-heading">
|
||
<h2 id="accessDialogTitle" data-i18n="authTitle">进入运营数据</h2>
|
||
<p id="accessDialogHint" data-i18n="authDescription">车辆全量信息与加氢量仅向获得授权的用户展示。</p>
|
||
</div>
|
||
<p class="access-session-note" data-i18n="authExpiry">本次授权有效期为 30 分钟,到期后将自动恢复为公开站点视图。</p>
|
||
<label class="access-code-field" for="accessCodeInput">
|
||
<span data-i18n="authCodeLabel">访问码</span>
|
||
<input id="accessCodeInput" type="password" autocomplete="current-password" enterkeyhint="done" data-i18n-placeholder="authCodePlaceholder" placeholder="输入访问码">
|
||
</label>
|
||
<p class="access-dialog-error" id="accessDialogError" role="alert" hidden></p>
|
||
<div class="access-dialog-actions">
|
||
<button type="button" class="access-cancel-btn" onclick="closeAccessDialog()" data-i18n="authCancel">暂不授权</button>
|
||
<button type="submit" class="access-submit-btn" id="accessSubmitBtn" data-i18n="authSubmit">验证并进入</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- 生产发布包不携带 node_modules;固定版本的 CDN 让中文地点保持拼音/首字母搜索能力。 -->
|
||
<script src="https://cdn.jsdelivr.net/npm/pinyin-pro@3.28.2/dist/index.js" crossorigin="anonymous"></script>
|
||
<script src="app.js?v=20260812113000"></script>
|
||
</body>
|
||
</html>
|