skill / index.html
chanfasf's picture
Upload index.html with huggingface_hub
81d8f02 verified
Raw History Blame Contribute Delete
10.5 kB
<!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">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Skills">
<meta name="theme-color" content="#0B0D12">
<title>Skills</title>
<link rel="manifest" href="./manifest.json">
<link rel="icon" type="image/svg+xml" href="./icon.svg">
<link rel="apple-touch-icon" href="./icon.svg">
<link rel="stylesheet" href="./style.css">
<script>
// 预判登录态,防刷新闪烁
if (sessionStorage.getItem('skill_auth') === '1') {
document.documentElement.classList.add('authed');
}
</script>
<style>
/* 未登录时隐藏主界面,防闪烁 */
html:not(.authed) body > :not(#loginGate):not(script):not(style) { display: none !important; }
#loginGate { display: flex; }
html.authed #loginGate { display: none; }
</style>
</head>
<body>
<!-- 商用登录页 -->
<div id="loginGate" class="login-gate" hidden>
<div class="login-card">
<div class="login-logo">💬</div>
<h2 class="login-title">Skills</h2>
<p class="login-sub">AI 助手 · 请输入访问密码</p>
<div class="login-input-wrap">
<input id="loginPwd" type="password" placeholder="访问密码" autocomplete="off" autocapitalize="off">
<button id="loginBtn" class="login-btn">进入</button>
</div>
<p id="loginErr" class="login-err" hidden>密码错误,请重试</p>
<p class="login-foot">© 2026 Skills · 仅授权用户可用</p>
</div>
</div>
<header class="header">
<div class="header-left">
<img src="./icon.svg" alt="S" class="avatar">
<div class="title-wrap">
<h1>Skills</h1>
<span class="subtitle">AI Assistant</span>
</div>
</div>
<span id="relayStatus" class="relay-status" title="本地中继状态">●</span>
<!-- 模型提供商快速切换:一键切智谱/CHATSAM/ChatGPT -->
<select id="quickProvSwitch" class="quick-prov-switch" aria-label="切换模型提供商" title="一键切换模型提供商">
<option value="zhipu">🧠 智谱 GLM</option>
<option value="chatsam">🪙 CHATSAM 免Key</option>
<option value="chatgpt">🤖 ChatGPT 官网</option>
</select>
<button id="settingsBtn" class="icon-btn" aria-label="设置">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
</svg>
</button>
</header>
<main id="messages" class="messages">
<div class="welcome" id="welcome">
<div class="welcome-icon">把对方的话发过来</div>
<p class="welcome-text">截图、文字、对方资料都行。<br>帮你看清局面,给你能直接发回去的话。</p>
<div class="suggest">
<button class="chip" data-q="她突然说「最近好累啊」,我该回什么">她喊累</button>
<button class="chip" data-q="她回我消息越来越慢了,咋办">回得越来越慢</button>
<button class="chip" data-q="她问我「你是不是对谁都这么好」怎么回">送命题</button>
<button class="chip" data-q="刚加的女生,第一句怎么开口不尴尬">开场白</button>
</div>
</div>
</main>
<div id="imgPreview" class="img-preview" style="display:none"></div>
<footer class="input-bar">
<button id="imgBtn" class="img-btn" type="button" aria-label="发截图">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2">
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
<circle cx="12" cy="13" r="4"/>
</svg>
</button>
<input id="imgInput" type="file" accept="image/*" hidden>
<textarea id="input" rows="1" placeholder="把对方发的话贴过来,或点左边发截图..." autocomplete="off"></textarea>
<button id="sendBtn" class="send-btn" aria-label="发送">
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M3.4 20.4l17.45-7.48a1 1 0 0 0 0-1.84L3.4 3.6a.993.993 0 0 0-1.39.91L2 9.12c0 .5.37.93.87.99L17 12 2.87 13.88c-.5.07-.87.5-.87 1l.01 4.61c0 .71.73 1.2 1.39.91z"/>
</svg>
</button>
</footer>
<!-- 设置面板 -->
<div id="settingsModal" class="modal" hidden>
<div class="modal-mask"></div>
<div class="modal-body">
<div class="modal-head">
<h2>设置</h2>
<button id="closeSettings" class="icon-btn" aria-label="关闭">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
</button>
</div>
<div class="field">
<label>女生档案(自动记录,互不混淆)</label>
<div id="girlsList" class="girls-list"></div>
</div>
<div class="field">
<label for="provider">AI 模型</label>
<select id="provider">
<option value="chatsam" selected>CHATSAM(内置号池·免配置·推荐)</option>
<option value="chatgpt">ChatGPT 官网多账号池(免费·无限制)</option>
<option value="zhipu">智谱 AI(GLM 系列模型轮调)</option>
</select>
</div>
<!-- 各平台 API 获取说明(切换 provider 自动更新) -->
<div id="providerGuide" class="provider-guide"></div>
<!-- 智谱模型余额显示 -->
<div id="zhipuQuotas" class="field" style="display:none"></div>
<!-- 本地中继状态 -->
<div id="relayBox" class="field relay-box">
<label>本地中继 <span id="relayDot" class="relay-dot offline">●</span></label>
<p class="hint" id="relayHint">本地中继未启动,正在使用 Cloudflare Worker(可能遇到 403 限流)</p>
<div class="relay-cmd">
<code id="relayCmd">node relay.mjs</code>
<button id="copyRelayCmd" class="ghost-btn" type="button" title="复制启动命令">复制</button>
</div>
</div>
<!-- 自定义 Base URL(不再需要,Worker 已硬编码) -->
<div class="field" id="baseUrlField" style="display:none">
<label for="baseUrl">Base URL(自定义后端)</label>
<input type="text" id="baseUrl" placeholder="http://localhost:3000/v1/chat/completions" autocomplete="off">
<p class="hint hint-tip">只对需要本机后端的平台显示(如 chatsam-hf)。填完整 endpoint,不要带 Bearer。</p>
</div>
<!-- 账号池(access_token / API Key,根据 provider 动态切换) -->
<div class="field" id="keyField">
<label id="keyFieldLabel">账号池(多 Key 自动轮询)</label>
<div id="keyList" class="key-list"></div>
<div class="key-add-row" id="keyAddRow">
<input type="text" id="newKeyName" placeholder="备注(如:账号1)" autocomplete="off">
<input type="password" id="newKeyVal" placeholder="粘贴 API Key / access_token" autocomplete="off">
<select id="newKeyModel" class="model-select">
<option value="gpt-4o" selected>GPT-4o</option>
<option value="gpt-4o-mini">GPT-4o mini</option>
<option value="gpt-4.1">GPT-4.1</option>
<option value="gpt-4.1-mini">GPT-4.1 mini</option>
<option value="o1">o1</option>
<option value="o1-mini">o1 mini</option>
<option value="o3">o3</option>
<option value="o3-mini">o3 mini</option>
</select>
<button id="addKeyBtn" class="add-key-btn" type="button">添加</button>
</div>
<a id="getKeyLink" class="hint" href="https://chatgpt.com" target="_blank" rel="noopener">→ 打开 chatgpt.com 登录账号拿 access_token</a>
<p class="hint hint-tip" id="keyHintTip">多账号 token 都加进来,自动轮询;单账号限流/失效不影响其他。Token 存本机 localStorage,不上传服务器。</p>
</div>
<!-- 账号仪表盘(类型 / 状态 / 账号信息 / 额度 / 恢复时间 / 成功 / 失败 / 操作) -->
<div class="field">
<div class="dash-head">
<label>账号仪表盘</label>
<button id="refreshAllBtn" class="ghost-btn" type="button" title="批量刷新所有账号的 session/探测">🔄 全部刷新</button>
</div>
<div class="dash-wrap">
<table class="dash-table">
<thead>
<tr>
<th>类型</th>
<th>状态</th>
<th>账号信息</th>
<th>额度</th>
<th>恢复时间</th>
<th>成功</th>
<th>失败</th>
<th>操作</th>
</tr>
</thead>
<tbody id="dashBody">
<tr><td colspan="8" class="empty-tip">还没添加账号</td></tr>
</tbody>
</table>
</div>
</div>
<div class="field-row">
<button id="clearChat" class="ghost-btn">清空对话</button>
<button id="saveSettings" class="primary-btn">保存</button>
</div>
<p class="footnote">Key 只存在你本机浏览器,不会上传。换设备需重新填。</p>
</div>
</div>
<script src="./app.js"></script>
</body>
</html>