🔍 升级 API 自动检测:一键检测可用模型(无需密钥)+ 网络环境自适应
- 新增 autoDetectModels() 函数:无密钥一键检测可用模型 - 新增 detectNetworkRegion():根据时区/语言检测国内/国际网络 - 新增 MODEL_CATALOG:内置模型目录(国内5家+国际3家,22个模型) - 新增 SERVER_PROXY_BASE:staging/local 自动指向生产服务器代理 - 修改 autoDetectAPI():无密钥时走一键检测,有密钥走原探测逻辑 - 修改 doSetup():支持服务器代理模式(无密钥直接进入对话) - 更新登录页 UI:一键检测按钮突出,自定义 API 折叠在 details 中 - 更新设置面板 UI:同步升级一键检测 + 自定义 API 折叠 - 修复侧边栏导航链接路径(../→相对路径) - Patch GUEST_API/TEAM_API proxyUrl for staging → 生产服务器 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/2b0b1a22-c312-4b46-ae3b-72e830c4470b
This commit is contained in:
parent
2cdf0af54d
commit
136c32ac02
293
docs/index.html
293
docs/index.html
|
|
@ -424,7 +424,6 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
|
|||
|
||||
<!-- 自定义 API(高级·使用自己的 API 密钥) -->
|
||||
<div id="login-dev" class="login-mode">
|
||||
<div class="sc-sec">🔒 API 密钥仅本次会话有效,关闭标签页即自动清除</div>
|
||||
|
||||
<div class="fg">
|
||||
<label>开发者身份</label>
|
||||
|
|
@ -445,27 +444,40 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
|
|||
</div>
|
||||
<div id="id-preview"></div>
|
||||
|
||||
<div class="fg">
|
||||
<label>API 端点 URL</label>
|
||||
<input type="text" id="sep" placeholder="https://api.example.com/v1">
|
||||
<small>输入你的 API 提供商端点地址(OpenAI 兼容格式)</small>
|
||||
</div>
|
||||
<div class="fg">
|
||||
<label>API 密钥</label>
|
||||
<div style="display:flex;gap:6px;align-items:stretch">
|
||||
<input type="password" id="sk" placeholder="粘贴你的 API 密钥" style="flex:1">
|
||||
<button onclick="autoDetectAPI('s')" id="sdet-btn" class="det-btn" title="自动检测可用模型">🔍 检测模型</button>
|
||||
</div>
|
||||
<small id="sk-err" style="color:var(--err);display:none">⚠️ 请输入 API 密钥</small>
|
||||
<small id="sdet-status" style="display:block;margin-top:4px;min-height:16px"></small>
|
||||
</div>
|
||||
<div class="fg">
|
||||
<label>选择模型</label>
|
||||
<select id="sm" disabled><option value="">— 请先检测可用模型 —</option></select>
|
||||
<small id="sm-hint">输入端点和密钥后,点击「🔍 检测模型」自动获取可用模型列表</small>
|
||||
<!-- 🚀 一键检测 -->
|
||||
<div style="background:rgba(79,142,247,0.08);border:1px solid rgba(79,142,247,0.25);border-radius:10px;padding:14px;margin-bottom:12px">
|
||||
<div style="font-size:13px;color:var(--text);margin-bottom:8px">🚀 <strong>一键检测可用模型</strong></div>
|
||||
<div style="font-size:12px;color:var(--dim);margin-bottom:10px;line-height:1.6">系统自动检测你的网络环境(国内/国际),连接服务器代理获取可用模型。无需输入 API 密钥。</div>
|
||||
<button onclick="autoDetectAPI('s')" id="sdet-btn" class="det-btn" style="width:100%;padding:10px;font-size:14px;border-radius:8px;background:var(--accent);color:#fff;border:none;cursor:pointer" title="自动检测网络环境和可用模型">🔍 自动检测</button>
|
||||
<small id="sdet-status" style="display:block;margin-top:8px;min-height:16px"></small>
|
||||
</div>
|
||||
|
||||
<button class="sc-btn" onclick="doSetup()">开始与铸渊对话 →</button>
|
||||
<div class="fg">
|
||||
<label>选择模型</label>
|
||||
<select id="sm" disabled onchange="onModelSelectChange('s')"><option value="">— 请先点击「🔍 自动检测」—</option></select>
|
||||
<small id="sm-hint">点击上方「🔍 自动检测」一键获取可用模型列表</small>
|
||||
</div>
|
||||
|
||||
<!-- 自定义 API 折叠区 -->
|
||||
<details style="margin-top:8px">
|
||||
<summary style="cursor:pointer;font-size:12px;color:var(--dim);padding:6px 0">🔧 自定义 API(使用自己的密钥)</summary>
|
||||
<div style="padding-top:8px">
|
||||
<div class="fg">
|
||||
<label>API 端点 URL</label>
|
||||
<input type="text" id="sep" placeholder="https://api.example.com/v1">
|
||||
<small>输入你的 API 提供商端点地址(OpenAI 兼容格式)</small>
|
||||
</div>
|
||||
<div class="fg">
|
||||
<label>API 密钥</label>
|
||||
<input type="password" id="sk" placeholder="粘贴你的 API 密钥" style="width:100%">
|
||||
<small id="sk-err" style="color:var(--err);display:none">⚠️ 请输入 API 密钥</small>
|
||||
<small style="color:var(--dim)">🔒 密钥仅本次会话有效,关闭标签页即自动清除</small>
|
||||
</div>
|
||||
<button onclick="autoDetectAPI('s')" class="det-btn" style="width:100%;margin-top:6px;padding:8px;border-radius:6px;cursor:pointer" title="使用自定义密钥检测模型">🔍 用自定义密钥检测模型</button>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<button class="sc-btn" onclick="doSetup()" style="margin-top:12px">开始与铸渊对话 →</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -490,9 +502,9 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
|
|||
<nav class="ls-nav">
|
||||
<button class="nav-tab active" data-view="announcements" onclick="navigateTo('announcements')">📢 公告栏</button>
|
||||
<button class="nav-tab" data-view="chat" onclick="navigateTo('chat')">💬 聊天</button>
|
||||
<button class="nav-tab" onclick="window.open('../persona-studio/frontend/index.html','_blank')">🧠 Studio</button>
|
||||
<button class="nav-tab" onclick="window.open('../status-board/','_blank')">📊 看板</button>
|
||||
<button class="nav-tab" onclick="window.open('../ticket-system/','_blank')">🎫 工单</button>
|
||||
<button class="nav-tab" onclick="window.open('persona-studio/','_blank')">🧠 Studio</button>
|
||||
<button class="nav-tab" onclick="window.open('status-board/','_blank')">📊 看板</button>
|
||||
<button class="nav-tab" onclick="window.open('ticket-system/','_blank')">🎫 工单</button>
|
||||
</nav>
|
||||
|
||||
<button class="ls-new-conv" onclick="newConvAndNav()">+ 新对话</button>
|
||||
|
|
@ -616,23 +628,36 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
|
|||
</div>
|
||||
</div>
|
||||
<div class="pb">
|
||||
<div class="sfg">
|
||||
<label>API 端点 URL</label>
|
||||
<input type="text" id="cep" placeholder="https://api.example.com/v1">
|
||||
</div>
|
||||
<div class="sfg">
|
||||
<label>选择模型</label>
|
||||
<select id="cm"></select>
|
||||
</div>
|
||||
<div class="sfg">
|
||||
<label>API 密钥</label>
|
||||
<div style="display:flex;gap:6px;align-items:stretch">
|
||||
<input type="password" id="ck" placeholder="留空 = 保持当前密钥不变;粘贴新密钥即替换" style="flex:1">
|
||||
<button onclick="autoDetectAPI('c')" id="cdet-btn" class="det-btn" title="自动检测提供商和可用模型">🔍 自动检测</button>
|
||||
<!-- 🚀 一键检测可用模型 -->
|
||||
<div style="background:rgba(79,142,247,0.08);border:1px solid rgba(79,142,247,0.25);border-radius:10px;padding:12px;margin-bottom:12px">
|
||||
<div style="display:flex;gap:8px;align-items:center">
|
||||
<button onclick="autoDetectAPI('c')" id="cdet-btn" class="det-btn" style="flex:1;padding:10px;font-size:13px;border-radius:8px;background:var(--accent);color:#fff;border:none;cursor:pointer" title="自动检测网络环境和可用模型">🔍 一键检测可用模型</button>
|
||||
</div>
|
||||
<small id="ck-hint" style="color:var(--dim)">🔒 密钥仅本次会话有效,关闭标签页自动清除</small>
|
||||
<small style="display:block;margin-top:6px;color:var(--dim);font-size:11px">自动检测网络环境,连接服务器代理获取可用模型(无需密钥)</small>
|
||||
<small id="cdet-status" style="display:block;margin-top:4px;min-height:14px"></small>
|
||||
</div>
|
||||
|
||||
<div class="sfg">
|
||||
<label>选择模型</label>
|
||||
<select id="cm" onchange="onModelSelectChange('c')"></select>
|
||||
</div>
|
||||
|
||||
<!-- 自定义 API 折叠区 -->
|
||||
<details style="margin-bottom:10px">
|
||||
<summary style="cursor:pointer;font-size:12px;color:var(--dim);padding:6px 0">🔧 自定义 API(使用自己的密钥)</summary>
|
||||
<div style="padding-top:8px">
|
||||
<div class="sfg">
|
||||
<label>API 端点 URL</label>
|
||||
<input type="text" id="cep" placeholder="https://api.example.com/v1">
|
||||
</div>
|
||||
<div class="sfg">
|
||||
<label>API 密钥</label>
|
||||
<input type="password" id="ck" placeholder="留空 = 保持当前密钥不变;粘贴新密钥即替换" style="width:100%">
|
||||
<small id="ck-hint" style="color:var(--dim)">🔒 密钥仅本次会话有效,关闭标签页自动清除</small>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<button class="sbtn2" onclick="saveSet()">💾 保存设置</button>
|
||||
|
||||
<div class="sec-ttl">身份设置</div>
|
||||
|
|
@ -665,11 +690,11 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
|
|||
|
||||
<div class="sec-ttl">使用说明</div>
|
||||
<p style="font-size:12px;color:var(--dim);line-height:1.8">
|
||||
1. 输入你的 API 端点和密钥,点击检测模型<br>
|
||||
2. 铸渊自动切换 💬 对话 / 🔨 构建 / 📋 审查 / 🧠 大脑 模式<br>
|
||||
3. 支持上传图片和文件(点击 📎 按钮或拖拽到对话区域)<br>
|
||||
4. 点 ⬇️ 下载单文件,放桌面直接打开使用<br>
|
||||
5. 支持任意 OpenAI 兼容接口(输入端点 + 密钥即可)
|
||||
1. 点击「🔍 一键检测可用模型」自动获取模型列表(无需密钥)<br>
|
||||
2. 如服务器代理可用,选择模型后直接对话<br>
|
||||
3. 也可展开「🔧 自定义 API」输入自己的端点和密钥<br>
|
||||
4. 铸渊自动切换 💬 对话 / 🔨 构建 / 📋 审查 / 🧠 大脑 模式<br>
|
||||
5. 支持上传图片和文件(点击 📎 按钮或拖拽到对话区域)
|
||||
</p>
|
||||
|
||||
<div class="sec-ttl" style="color:#ef4444;margin-top:16px">⚠️ 危险操作</div>
|
||||
|
|
@ -822,6 +847,25 @@ const KNOWN_ENDPOINTS = [
|
|||
{label:'智谱 AI', base:'https://open.bigmodel.cn/api/paas/v4'},
|
||||
];
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 内置模型目录(按网络区域分类)
|
||||
// 一键检测时,根据用户网络环境自动推荐可用模型
|
||||
// ═══════════════════════════════════════════════════════
|
||||
const MODEL_CATALOG = {
|
||||
domestic: [
|
||||
{provider:'yunwu', label:'云雾 AI(推荐·聚合)', models:['deepseek-chat','deepseek-reasoner','gpt-4o','claude-sonnet-4-20250514','gemini-2.5-pro-preview-05-06'], endpoint:'https://api.yunwu.ai/v1'},
|
||||
{provider:'deepseek', label:'DeepSeek(国内直连)', models:['deepseek-chat','deepseek-reasoner'], endpoint:'https://api.deepseek.com/v1'},
|
||||
{provider:'qwen', label:'通义千问 Qwen', models:['qwen-max','qwen-plus','qwen-turbo'], endpoint:'https://dashscope.aliyuncs.com/compatible-mode/v1'},
|
||||
{provider:'moonshot', label:'Moonshot / Kimi', models:['moonshot-v1-8k','moonshot-v1-32k','moonshot-v1-128k'], endpoint:'https://api.moonshot.cn/v1'},
|
||||
{provider:'zhipu', label:'智谱 AI', models:['glm-4','glm-4-flash'], endpoint:'https://open.bigmodel.cn/api/paas/v4'},
|
||||
],
|
||||
international: [
|
||||
{provider:'openai', label:'OpenAI', models:['gpt-4o','gpt-4-turbo','gpt-4o-mini'], endpoint:'https://api.openai.com/v1'},
|
||||
{provider:'anthropic', label:'Anthropic', models:['claude-sonnet-4-20250514','claude-3-5-sonnet-20241022'], endpoint:'https://api.anthropic.com/v1'},
|
||||
{provider:'google', label:'Google Gemini', models:['gemini-2.5-pro','gemini-2.0-flash'], endpoint:'https://generativelanguage.googleapis.com/v1beta/openai'},
|
||||
]
|
||||
};
|
||||
|
||||
const MODES = {
|
||||
chat: {e:'💬',l:'对话模式', c:'var(--mc)'},
|
||||
build: {e:'🔨',l:'构建模式', c:'var(--mb)'},
|
||||
|
|
@ -938,6 +982,29 @@ const HOLOLAKE_ENV = (function(){
|
|||
})();
|
||||
window.HOLOLAKE_ENV = HOLOLAKE_ENV;
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 服务器代理基址(staging/local → 调用生产服务器已配置的 API 密钥)
|
||||
// ═══════════════════════════════════════════════════════
|
||||
const SERVER_PROXY_BASE = HOLOLAKE_ENV === 'production' ? '' : 'https://guanghulab.com';
|
||||
|
||||
// Patch proxy URLs for staging/local: point to production server
|
||||
if(HOLOLAKE_ENV !== 'production'){
|
||||
GUEST_API.proxyUrl = SERVER_PROXY_BASE + '/api/chat';
|
||||
TEAM_API.proxyUrl = SERVER_PROXY_BASE + '/api/chat';
|
||||
}
|
||||
|
||||
// 检测用户网络环境(国内/国际)
|
||||
function detectNetworkRegion(){
|
||||
var tz = '';
|
||||
try{ tz = Intl.DateTimeFormat().resolvedOptions().timeZone || ''; }catch(e){}
|
||||
var lang = (navigator.language || navigator.userLanguage || '').toLowerCase();
|
||||
var chinaZones = ['Asia/Shanghai','Asia/Chongqing','Asia/Harbin','Asia/Urumqi','Asia/Hong_Kong','Asia/Macau','Asia/Taipei'];
|
||||
if(chinaZones.some(function(z){ return tz.indexOf(z) >= 0; }) || lang.indexOf('zh') === 0){
|
||||
return 'domestic';
|
||||
}
|
||||
return 'international';
|
||||
}
|
||||
|
||||
function ls(k){return localStorage.getItem(k)}
|
||||
function lss(k,v){localStorage.setItem(k,v)}
|
||||
|
||||
|
|
@ -1414,20 +1481,23 @@ function switchLoginMode(mode){
|
|||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// AUTO-DETECT PROVIDER & MODELS
|
||||
// v4.0: 无密钥一键检测 + 网络环境自适应 + 服务器代理
|
||||
// 有密钥 → 原逻辑探测端点;无密钥 → 服务器代理 / 内置目录
|
||||
// ═══════════════════════════════════════════════════════
|
||||
async function autoDetectAPI(ctx){
|
||||
const keyEl = document.getElementById(ctx==='s'?'sk':'ck');
|
||||
const statusEl = document.getElementById(ctx==='s'?'sdet-status':'cdet-status');
|
||||
const btnEl = document.getElementById(ctx==='s'?'sdet-btn':'cdet-btn');
|
||||
const mdlSel = document.getElementById(ctx==='s'?'sm':'cm');
|
||||
const key = keyEl.value.trim();
|
||||
const key = keyEl ? keyEl.value.trim() : '';
|
||||
|
||||
// 无密钥 → 一键自动检测(服务器代理 / 内置目录)
|
||||
if(!key){
|
||||
statusEl.innerHTML='<span style="color:var(--warn)">⚠️ 请先输入 API 密钥</span>';
|
||||
await autoDetectModels(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build list of endpoints to probe: user's endpoint first, then known fallbacks
|
||||
// 有密钥 → 探测用户端点获取模型列表
|
||||
const userBase = (document.getElementById(ctx==='s'?'sep':'cep')?.value||'').trim();
|
||||
const candidates = [];
|
||||
if(userBase) candidates.push({label:userBase, base:userBase});
|
||||
|
|
@ -1455,11 +1525,9 @@ async function autoDetectAPI(ctx){
|
|||
const mdls = (data.data||[]).map(function(m){return m.id;}).filter(Boolean).sort();
|
||||
if(!mdls.length) continue;
|
||||
|
||||
// Fill endpoint field with matched endpoint
|
||||
const epEl = document.getElementById(ctx==='s'?'sep':'cep');
|
||||
if(epEl) epEl.value = base;
|
||||
|
||||
// Fill model dropdown with detected models
|
||||
if(mdlSel){
|
||||
mdlSel.innerHTML = mdls.map(function(m){return '<option value="'+m+'">'+m+'</option>';}).join('');
|
||||
mdlSel.disabled = false;
|
||||
|
|
@ -1477,12 +1545,106 @@ async function autoDetectAPI(ctx){
|
|||
}
|
||||
|
||||
btnEl.disabled = false;
|
||||
btnEl.textContent = '🔍 检测模型';
|
||||
btnEl.textContent = '🔍 自动检测';
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 一键检测可用模型(无需 API 密钥)
|
||||
// 1. 检测网络环境(国内/国际)
|
||||
// 2. 尝试连接服务器代理获取实时模型列表
|
||||
// 3. 降级使用内置模型目录
|
||||
// ═══════════════════════════════════════════════════════
|
||||
async function autoDetectModels(ctx){
|
||||
const statusEl = document.getElementById(ctx==='s'?'sdet-status':'cdet-status');
|
||||
const btnEl = document.getElementById(ctx==='s'?'sdet-btn':'cdet-btn');
|
||||
const mdlSel = document.getElementById(ctx==='s'?'sm':'cm');
|
||||
const epEl = document.getElementById(ctx==='s'?'sep':'cep');
|
||||
const hintEl = document.getElementById(ctx==='s'?'sm-hint':'');
|
||||
|
||||
btnEl.disabled = true;
|
||||
btnEl.textContent = '⏳ 检测中…';
|
||||
statusEl.innerHTML = '<span style="color:var(--dim)">🌐 正在检测网络环境…</span>';
|
||||
|
||||
const region = detectNetworkRegion();
|
||||
const regionLabel = region === 'domestic' ? '🇨🇳 国内网络' : '🌍 国际网络';
|
||||
statusEl.innerHTML = '<span style="color:var(--dim)">'+regionLabel+' · 正在获取可用模型…</span>';
|
||||
|
||||
// 尝试连接服务器代理获取实时模型列表
|
||||
let serverModels = null;
|
||||
const proxyBase = SERVER_PROXY_BASE || location.origin;
|
||||
try{
|
||||
const ctrl = new AbortController();
|
||||
const tid = setTimeout(function(){ctrl.abort();}, 5000);
|
||||
const res = await fetch(proxyBase+'/api/models',{signal:ctrl.signal});
|
||||
clearTimeout(tid);
|
||||
if(res.ok){
|
||||
const data = await res.json();
|
||||
const list = data.data || data.models || [];
|
||||
serverModels = list.map(function(m){return typeof m==='string'?m:m.id;}).filter(Boolean).sort();
|
||||
}
|
||||
}catch(e){console.debug('[AutoDetect] Server probe failed:',e.message);}
|
||||
|
||||
let source, totalCount = 0;
|
||||
|
||||
if(serverModels && serverModels.length > 0){
|
||||
// 服务器代理可用 → 使用服务器模型列表
|
||||
source = '服务器代理';
|
||||
totalCount = serverModels.length;
|
||||
if(mdlSel){
|
||||
mdlSel.innerHTML = serverModels.map(function(m){return '<option value="'+m+'" data-proxy="1">'+m+'</option>';}).join('');
|
||||
mdlSel.disabled = false;
|
||||
}
|
||||
if(epEl) epEl.value = proxyBase + '/api/chat';
|
||||
window._autoDetectServerProxy = true;
|
||||
} else {
|
||||
// 降级使用内置模型目录(按网络区域排序)
|
||||
source = '内置模型库';
|
||||
const primary = region === 'domestic' ? MODEL_CATALOG.domestic : MODEL_CATALOG.international;
|
||||
const secondary = region === 'domestic' ? MODEL_CATALOG.international : MODEL_CATALOG.domestic;
|
||||
const catalog = primary.concat(secondary);
|
||||
|
||||
if(mdlSel){
|
||||
let html = '';
|
||||
for(let i=0;i<catalog.length;i++){
|
||||
const p = catalog[i];
|
||||
html += '<optgroup label="'+p.label+'">';
|
||||
for(let j=0;j<p.models.length;j++){
|
||||
html += '<option value="'+p.models[j]+'" data-endpoint="'+p.endpoint+'" data-provider="'+p.provider+'">'+p.models[j]+'</option>';
|
||||
totalCount++;
|
||||
}
|
||||
html += '</optgroup>';
|
||||
}
|
||||
mdlSel.innerHTML = html;
|
||||
mdlSel.disabled = false;
|
||||
// 自动选择第一个模型并设置对应端点
|
||||
onModelSelectChange(ctx);
|
||||
}
|
||||
window._autoDetectServerProxy = false;
|
||||
}
|
||||
|
||||
statusEl.innerHTML = '<span style="color:var(--ok)">✅ 检测成功('+source+' · '+regionLabel+')· 发现 <strong>'+totalCount+'</strong> 个可用模型</span>'
|
||||
+ (serverModels ? '<br><span style="color:var(--ok);font-size:11px">🔑 已连接服务器代理,无需输入 API 密钥</span>' : '<br><span style="color:var(--warn);font-size:11px">⚠️ 服务器暂不可达,请输入对应提供商的 API 密钥后使用</span>');
|
||||
|
||||
if(hintEl) hintEl.textContent = serverModels ? '已连接服务器代理,选择模型后可直接开始对话' : '选择模型后,请输入对应提供商的 API 密钥';
|
||||
|
||||
btnEl.disabled = false;
|
||||
btnEl.textContent = '🔍 自动检测';
|
||||
}
|
||||
|
||||
// 模型选择变更 → 自动切换端点
|
||||
function onModelSelectChange(ctx){
|
||||
const mdlSel = document.getElementById(ctx==='s'?'sm':'cm');
|
||||
const epEl = document.getElementById(ctx==='s'?'sep':'cep');
|
||||
if(!mdlSel || !epEl) return;
|
||||
const opt = mdlSel.options[mdlSel.selectedIndex];
|
||||
if(!opt) return;
|
||||
const ep = opt.getAttribute('data-endpoint');
|
||||
if(ep) epEl.value = ep;
|
||||
}
|
||||
|
||||
function doSetup(){
|
||||
const un = document.getElementById('suid').value;
|
||||
const k = document.getElementById('sk').value.trim();
|
||||
const k = document.getElementById('sk')?.value?.trim() || '';
|
||||
const base = (document.getElementById('sep')?.value||'').trim();
|
||||
const md = document.getElementById('sm').value;
|
||||
const errEl = document.getElementById('sk-err');
|
||||
|
|
@ -1491,14 +1653,35 @@ function doSetup(){
|
|||
alert('请选择你的开发者身份');
|
||||
return;
|
||||
}
|
||||
if(!k){errEl.style.display='block';return;}
|
||||
errEl.style.display='none';
|
||||
if(!base){
|
||||
alert('请输入 API 端点 URL');
|
||||
if(!md){
|
||||
alert('请先点击「🔍 自动检测」检测可用模型,然后选择一个模型');
|
||||
return;
|
||||
}
|
||||
if(!md){
|
||||
alert('请先点击「🔍 检测模型」检测可用模型,然后选择一个模型');
|
||||
|
||||
// 服务器代理模式(一键检测,无需密钥)
|
||||
if(window._autoDetectServerProxy && !k){
|
||||
A.demo = true;
|
||||
A.teamMode = true;
|
||||
A.key = '';
|
||||
A.prov = 'custom';
|
||||
A.mdl = md;
|
||||
A.base = base;
|
||||
lss('zy_teammode','1');
|
||||
lss('zy_base',base); lss('zy_mdl',md); lss('zy_prov','proxy');
|
||||
setIdentity(un, '');
|
||||
showApp();
|
||||
return;
|
||||
}
|
||||
|
||||
// 自定义 API 模式(需要密钥)
|
||||
if(!k){
|
||||
if(errEl) errEl.style.display='block';
|
||||
alert('请输入 API 密钥,或点击「🔍 自动检测」使用服务器代理');
|
||||
return;
|
||||
}
|
||||
if(errEl) errEl.style.display='none';
|
||||
if(!base){
|
||||
alert('请输入 API 端点 URL');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue