Files
nba-fan-hub/static/admin.html
T

198 lines
11 KiB
HTML
Raw 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">
<title>管理后台 - NBA球迷大全</title>
<style>
:root { --bg:#0d1117; --bg2:#161b22; --card:#1c2333; --line:#2d3748; --txt:#e6edf3; --sub:#8b949e;
--orange:#f97316; --orange2:#fb923c; --blue:#38bdf8; --green:#34d399; --red:#f87171; --radius:12px; }
* { margin:0; padding:0; box-sizing:border-box; }
body { background:var(--bg); color:var(--txt); font-family:"PingFang SC","Microsoft YaHei",system-ui,sans-serif; font-size:14px; }
/* 登录 */
.login-view { min-height:100vh; display:flex; align-items:center; justify-content:center; }
.login-box { background:var(--bg2); border:1px solid var(--line); border-radius:16px; padding:36px 40px; width:360px; text-align:center; }
.login-box h1 { font-size:20px; margin-bottom:22px; color:var(--orange2); }
.login-box input { width:100%; background:var(--bg); border:1px solid var(--line); color:var(--txt); border-radius:10px; padding:11px 14px; font-size:14px; outline:none; margin-bottom:12px; }
.login-box input:focus { border-color:var(--orange2); }
.login-box button { width:100%; background:linear-gradient(135deg,#f97316,#ea580c); border:none; color:#fff; border-radius:10px; padding:11px; font-size:15px; font-weight:600; cursor:pointer; }
.login-box button:hover { filter:brightness(1.1); }
.err { color:var(--red); font-size:13px; margin-top:10px; min-height:18px; }
/* 主布局 */
.main { display:flex; min-height:100vh; }
.side { width:210px; background:var(--bg2); border-right:1px solid var(--line); padding:16px 10px; flex-shrink:0; position:sticky; top:0; height:100vh; overflow-y:auto; }
.side-head { font-size:16px; font-weight:700; color:var(--orange2); padding:4px 10px 14px; }
.side nav button, .side nav a { display:block; width:100%; text-align:left; background:transparent; border:none; color:var(--sub); padding:8px 12px; border-radius:8px; cursor:pointer; font-size:13.5px; text-decoration:none; margin-bottom:2px; transition:.15s; }
.side nav button:hover, .side nav a:hover { color:var(--txt); background:var(--card); }
.side nav button.active { color:var(--orange2); background:rgba(249,115,22,.1); font-weight:600; }
.nav-group { color:var(--sub); font-size:11px; padding:12px 12px 4px; letter-spacing:1px; }
.content { flex:1; padding:22px 26px; min-width:0; }
/* 顶栏 */
.bar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:16px; }
.bar h2 { font-size:19px; flex:1; }
.bar input { background:var(--bg2); border:1px solid var(--line); color:var(--txt); border-radius:999px; padding:7px 14px; font-size:13px; outline:none; min-width:200px; }
.bar input:focus { border-color:var(--orange2); }
.btn { background:var(--orange); border:none; color:#fff; border-radius:999px; padding:8px 16px; cursor:pointer; font-size:13px; }
.btn:hover { filter:brightness(1.1); }
.btn.ghost { background:transparent; border:1px solid var(--line); color:var(--sub); }
.btn.danger { background:rgba(248,113,113,.15); color:var(--red); border:1px solid #7f1d1d; }
.btn.sm { padding:4px 10px; font-size:12px; }
/* 表格 */
.tbl-wrap { overflow-x:auto; background:var(--card); border:1px solid var(--line); border-radius:var(--radius); }
table { width:100%; border-collapse:collapse; }
th, td { padding:9px 11px; text-align:left; font-size:13px; border-bottom:1px solid var(--line); white-space:nowrap; max-width:260px; overflow:hidden; text-overflow:ellipsis; }
th { background:var(--bg2); color:var(--sub); font-weight:600; font-size:12px; position:sticky; top:0; }
tr:hover td { background:rgba(249,115,22,.05); }
td.num { text-align:center; }
.row-ops { display:flex; gap:6px; }
.pager { display:flex; align-items:center; gap:10px; justify-content:center; margin-top:14px; color:var(--sub); font-size:13px; }
/* 统计卡 */
.stats-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; }
.stat-card { background:var(--card); border:1px solid var(--line); border-radius:var(--radius); padding:16px; text-align:center; }
.stat-card .n { font-size:26px; font-weight:800; color:var(--orange2); }
.stat-card .t { color:var(--sub); font-size:12.5px; margin-top:4px; }
/* 配置表单 */
.cfg-form { max-width:720px; display:flex; flex-direction:column; gap:14px; }
.cfg-form label { display:block; color:var(--sub); font-size:12.5px; margin-bottom:6px; }
.cfg-form input, .cfg-form textarea, .cfg-form select { width:100%; background:var(--bg2); border:1px solid var(--line); color:var(--txt); border-radius:10px; padding:9px 12px; font-size:13.5px; outline:none; font-family:inherit; }
.cfg-form input:focus, .cfg-form textarea:focus { border-color:var(--orange2); }
.cfg-form textarea { min-height:90px; resize:vertical; }
.cfg-form .row2 { display:flex; gap:14px; }
.cfg-form .row2 > div { flex:1; }
.tip { color:var(--sub); font-size:12px; margin-top:4px; }
.form-actions { display:flex; gap:10px; margin-top:6px; }
/* 弹窗 */
.modal { position:fixed; inset:0; background:rgba(0,0,0,.7); display:flex; align-items:center; justify-content:center; z-index:100; padding:20px; }
.modal.hidden { display:none; }
.modal-box { background:var(--bg2); border:1px solid var(--line); border-radius:16px; max-width:760px; width:100%; max-height:88vh; overflow-y:auto; padding:24px 26px; position:relative; }
.modal-close { position:absolute; top:12px; right:14px; background:none; border:none; color:var(--sub); font-size:18px; cursor:pointer; }
.modal-close:hover { color:var(--txt); }
.modal-box h2 { font-size:18px; margin-bottom:16px; }
.form-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:12px; }
.form-grid label { display:block; color:var(--sub); font-size:12px; margin-bottom:5px; }
.form-grid input, .form-grid select, .form-grid textarea { width:100%; background:var(--bg); border:1px solid var(--line); color:var(--txt); border-radius:8px; padding:8px 10px; font-size:13px; outline:none; font-family:inherit; }
.form-grid input:focus, .form-grid select:focus, .form-grid textarea:focus { border-color:var(--orange2); }
.form-grid .full { grid-column:1/-1; }
.form-grid textarea { min-height:70px; resize:vertical; }
.form-grid .ro { opacity:.5; }
.modal-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:18px; }
.hidden { display:none !important; }
.badge { display:inline-block; background:rgba(249,115,22,.12); color:var(--orange2); border-radius:6px; padding:1px 7px; font-size:11px; }
</style>
</head>
<body>
<!-- 登录 -->
<div id="login-view" class="login-view">
<div class="login-box">
<h1>⚙️ NBA球迷大全 管理后台</h1>
<input type="password" id="login-pw" placeholder="管理员密码" autocomplete="current-password">
<button id="login-btn">登 录</button>
<div class="err" id="login-err"></div>
</div>
</div>
<!-- 主界面 -->
<div id="main-view" class="main hidden">
<aside class="side">
<div class="side-head">⚙️ 管理后台</div>
<nav>
<button data-page="stats" class="active">📊 仪表盘</button>
<div class="nav-group">数据管理</div>
<button data-page="teams">🏟️ 球队</button>
<button data-page="players">⭐ 球员</button>
<button data-page="games">📅 比赛</button>
<button data-page="game_player_stats">📊 技术统计</button>
<button data-page="standings">🏆 排名</button>
<button data-page="news">📰 新闻/百科</button>
<button data-page="persons">👥 人物</button>
<button data-page="sports">🏈 运动项目</button>
<button data-page="leagues">🏀 联赛</button>
<div class="nav-group">系统</div>
<button data-page="config">🎛️ 站点配置</button>
<a href="/" target="_blank">🌐 返回前台</a>
<button id="logout-btn">🚪 退出登录</button>
</nav>
</aside>
<main class="content">
<div id="page-stats" class="page">
<h2 style="margin-bottom:16px">📊 数据概览</h2>
<div class="stats-grid" id="stats-grid"></div>
</div>
<div id="page-table" class="page hidden">
<div class="bar">
<h2 id="table-title"></h2>
<input id="tbl-search" placeholder="搜索关键字...">
<button class="btn ghost" id="tbl-search-btn">🔍 搜索</button>
<button class="btn" id="tbl-add"> 新增</button>
</div>
<div class="tbl-wrap" id="tbl-wrap"></div>
<div class="pager" id="tbl-pager"></div>
</div>
<div id="page-config" class="page hidden">
<h2 style="margin-bottom:16px">🎛️ 站点配置(保存后前台即时生效)</h2>
<div class="cfg-form">
<div class="row2">
<div><label>站点名称</label><input id="cfg-site_name"></div>
<div><label>站点副标题</label><input id="cfg-site_subtitle"></div>
</div>
<div><label>开场白(支持 Markdown</label><textarea id="cfg-welcome_text"></textarea></div>
<div class="row2">
<div><label>快捷问题提示语</label><input id="cfg-welcome_hint"></div>
<div><label>页脚文字</label><input id="cfg-footer_text"></div>
</div>
<div>
<label>快捷问题(每行一个,前台"试试"语句与快捷按钮同步生效)</label>
<textarea id="cfg-suggestions" style="min-height:160px"></textarea>
<div class="tip">💡 一行一个问题。保存后刷新前台页面即可看到新的快捷问题。</div>
</div>
<div class="row2">
<div><label>对话中底部快捷问题预测个数(默认3,范围1-6)</label><input type="number" id="cfg-suggestion_count" min="1" max="6">
<div class="tip">对话进行中,大模型根据上下文预测用户可能追问的问题数量(每个≤30字)</div></div>
</div>
<div class="row2">
<div><label>管理员密码(留空则不修改)</label><input type="password" id="cfg-admin_password" placeholder="••••••"></div>
<div><label>实体标记模式</label><select id="cfg-entity_mark_mode">
<option value="first">只标记首次出现(推荐)</option>
<option value="all">全部标记</option>
</select>
<div class="tip">对话回答中球队/球员/人物等特殊标记策略</div></div>
</div>
<div class="form-actions">
<button class="btn" id="cfg-save">💾 保存配置</button>
<button class="btn ghost" id="cfg-reset-sug">↺ 恢复默认快捷问题</button>
</div>
<div class="err" id="cfg-msg"></div>
</div>
</div>
</main>
</div>
<!-- 编辑弹窗 -->
<div id="modal" class="modal hidden">
<div class="modal-box">
<button class="modal-close" id="modal-close"></button>
<h2 id="modal-title"></h2>
<div class="form-grid" id="modal-form"></div>
<div class="modal-actions">
<button class="btn ghost" id="modal-cancel">取消</button>
<button class="btn" id="modal-save">保存</button>
</div>
</div>
</div>
<script src="/static/admin.js"></script>
</body>
</html>