198 lines
11 KiB
HTML
198 lines
11 KiB
HTML
<!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>
|