Files
yuqianhe 3e27017e42 feat: add auth, db, gateway, email, ratelimit, geoblock modules and new handlers
- New CLI commands: key, user
- New internal modules: auth (middleware, password, user), db (db, logs, products), email, gateway (gateway, hooks, middlewares), handler (admin, auth, dev, log, product, settings), middleware/geoblock, ratelimit
- New demo frontend page
- Updated config, server, analytics, stats, and existing frontend pages
2026-06-26 21:32:51 +09:00

162 lines
8.1 KiB
HTML
Raw Permalink 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.0">
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Sol148 Video - 视频浏览</title>
<link rel="stylesheet" href="/videoapp/style.css?v=3">
</head>
<body>
<!-- 顶部导航 -->
<nav class="navbar">
<div class="nav-inner">
<a href="/video" class="logo">🎬 Sol148 Video</a>
<div class="nav-links">
<a href="/video#/browse" class="nav-link">浏览</a>
<a href="/video#/categories" class="nav-link">分类</a>
<a href="/video#/search" class="nav-link">搜索</a>
</div>
<div class="nav-stats" id="navStats">
<span title="QPS"><b id="navQPS">--</b></span>
<span title="活跃连接">🔗 <b id="navConn">--</b></span>
<span title="平均延迟">⏱️ <b id="navLat">--</b>ms</span>
</div>
</div>
</nav>
<!-- 主内容区SPA 路由切换) -->
<main id="app">
<!-- 首页 -->
<section id="page-home" class="page">
<div class="hero">
<h1>探索精彩视频内容</h1>
<p>通过 sol148-extractor API 驱动的视频浏览平台</p>
<div class="hero-actions">
<button class="btn btn-primary" onclick="navigate('#/browse')">开始浏览</button>
<button class="btn btn-outline" onclick="navigate('#/categories')">查看分类</button>
</div>
</div>
<div class="section">
<h2>🔥 热门分类</h2>
<div class="category-grid" id="homeCategories"></div>
</div>
<div class="section">
<h2>⚡ 实时服务状态</h2>
<div class="stats-bar" id="homeStats"></div>
</div>
</section>
<!-- 分类浏览页 -->
<section id="page-browse" class="page hidden">
<div class="browse-header">
<h2 id="browseTitle">最近更新</h2>
<div class="browse-controls">
<select id="categorySelect" onchange="loadCategoryPage()"></select>
<button class="btn btn-sm" onclick="prevPage()" id="btnPrev">◀ 上一页</button>
<span id="pageInfo">第 1 页</span>
<button class="btn btn-sm" onclick="nextPage()" id="btnNext">下一页 ▶</button>
<span class="page-jump-group">
跳至 <input type="number" class="page-jump-input" id="pageJumpTop" min="1" placeholder="页码" onkeydown="if(event.key==='Enter')jumpToPage('top')">
<button class="btn btn-sm" onclick="jumpToPage('top')">GO</button>
</span>
</div>
</div>
<div class="video-grid" id="videoGrid"></div>
<div class="loading" id="browseLoading" style="display:none;">加载中...</div>
<div class="browse-footer-pagination" id="browseFooterPagination">
<button class="btn btn-sm" onclick="prevPage()" id="btnPrevBottom">◀ 上一页</button>
<span id="pageInfoBottom">第 1 页</span>
<button class="btn btn-sm" onclick="nextPage()" id="btnNextBottom">下一页 ▶</button>
<span class="page-jump-group">
跳至 <input type="number" class="page-jump-input" id="pageJumpBottom" min="1" placeholder="页码" onkeydown="if(event.key==='Enter')jumpToPage('bottom')">
<button class="btn btn-sm" onclick="jumpToPage('bottom')">GO</button>
</span>
</div>
</section>
<!-- 分类列表页 -->
<section id="page-categories" class="page hidden">
<h2>📂 视频分类</h2>
<div class="category-list" id="categoryList"></div>
</section>
<!-- 搜索页 -->
<section id="page-search" class="page hidden">
<h2>🔍 搜索视频</h2>
<div class="search-bar">
<input type="text" id="searchInput" placeholder="输入关键词搜索(暂搜索标题)..." onkeydown="if(event.key==='Enter')doSearch()">
<button class="btn btn-primary" onclick="doSearch()">搜索</button>
</div>
<div class="video-grid" id="searchResults"></div>
<div class="loading" id="searchLoading" style="display:none;">搜索中...</div>
</section>
<!-- 视频详情页 -->
<section id="page-watch" class="page hidden">
<div class="watch-container">
<div class="video-player">
<div class="player-wrapper" id="playerWrapper">
<div class="player-placeholder" id="playerBox">
<div class="play-icon"></div>
<p id="playerLabel">正在提取视频源...</p>
<p class="player-hint" id="playerHint"></p>
</div>
<div id="dplayerContainer" class="hidden"></div>
<div class="player-error-overlay hidden" id="playerError">
<div class="error-icon">⚠️</div>
<p id="playerErrorMsg">无法播放</p>
<p id="playerErrorHint"></p>
</div>
</div>
<div class="player-status hidden" id="playerStatus"></div>
<div class="player-mode" id="playerMode">
<span class="mode-label">加载模式</span>
<div class="mode-toggle" id="modeToggle" onclick="togglePlayMode()" title="切换视频加载方式">
<span class="mode-option active" data-mode="proxy">🛡️ 代理</span>
<span class="mode-option" data-mode="direct">🔗 直连</span>
<span class="mode-slider"></span>
</div>
</div>
</div>
<div class="video-detail">
<h2 id="videoTitle">--</h2>
<div class="video-meta" id="videoMeta"></div>
<div class="video-actions">
<button class="btn btn-primary" id="btnExtract" onclick="extractCurrent()">🔗 重新提取</button>
<button class="btn btn-outline" id="btnCopyURL" onclick="copyVideoURL()" disabled>📋 复制源地址</button>
<a class="btn btn-outline hidden" id="btnOpenNew" target="_blank" rel="noopener">📥 下载</a>
</div>
<div class="video-source hidden" id="videoSourceBox">
<label>视频源地址:</label>
<input type="text" id="videoSourceURL" readonly onclick="this.select()">
</div>
</div>
</div>
<div class="section" id="videoRelated"></div>
</section>
<!-- 作者页 -->
<section id="page-author" class="page hidden">
<h2 id="authorName">作者</h2>
<div class="video-grid" id="authorVideos"></div>
<div class="loading" id="authorLoading" style="display:none;">加载中...</div>
</section>
</main>
<footer>
<span>Sol148 Video Explorer</span>
<span>Powered by api-server (Gin + Cobra + ip2region)</span>
<span>Data via sol148-extractor API</span>
</footer>
<script src="https://cdn.jsdelivr.net/npm/artplayer/dist/artplayer.js"></script>
<script src="https://cdn.jsdelivr.net/npm/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js"></script>
<script src="/videoapp/app.js?v=3"></script>
</body>
</html>