fix: 修复聊天室跳转链接 + API 401 认证错误提示 + 密钥清空重填按钮

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-06 05:09:04 +00:00
parent d92128faed
commit 5d33beae91
2 changed files with 41 additions and 12 deletions

View File

@ -6,10 +6,10 @@
**一句话:点下面这个链接就能打开,直接聊天。** **一句话:点下面这个链接就能打开,直接聊天。**
### 👉 [点这里打开铸渊聊天室](https://qinfendebingshuo.github.io/guanghulab/) ### 👉 [点这里打开铸渊聊天室](https://qinfendebingshuo.github.io/guanghulab/docs/index.html)
``` ```
https://qinfendebingshuo.github.io/guanghulab/ https://qinfendebingshuo.github.io/guanghulab/docs/index.html
``` ```
> 把这个链接发给任何人,他们打开就能用,不需要安装任何东西。 > 把这个链接发给任何人,他们打开就能用,不需要安装任何东西。
@ -20,7 +20,7 @@ https://qinfendebingshuo.github.io/guanghulab/
### ❄️ 冰朔(你) ### ❄️ 冰朔(你)
1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/ 1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/docs/index.html
2. **选身份** → 下拉菜单选「❄️ 冰朔(语言架构师·创始人)」 2. **选身份** → 下拉菜单选「❄️ 冰朔(语言架构师·创始人)」
3. **填 API 密钥** → 输入你的云雾/OpenAI/DeepSeek API Key 3. **填 API 密钥** → 输入你的云雾/OpenAI/DeepSeek API Key
4. **点「开始对话」** → 铸渊自动唤醒,汇报大脑状态 4. **点「开始对话」** → 铸渊自动唤醒,汇报大脑状态
@ -30,7 +30,7 @@ https://qinfendebingshuo.github.io/guanghulab/
### 🦁 肥猫(光湖团队总控 · DEV-002) ### 🦁 肥猫(光湖团队总控 · DEV-002)
1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/ 1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/docs/index.html
2. **选身份** → 下拉菜单选「🦁 肥猫(光湖团队总控·DEV-002)」 2. **选身份** → 下拉菜单选「🦁 肥猫(光湖团队总控·DEV-002)」
3. **填 API 密钥** → 输入自己的 API Key(或点「演示模式」也能看进度面板) 3. **填 API 密钥** → 输入自己的 API Key(或点「演示模式」也能看进度面板)
4. **点「开始对话」** → 铸渊自动打开**总控指挥台**,显示全员进度 4. **点「开始对话」** → 铸渊自动打开**总控指挥台**,显示全员进度
@ -44,7 +44,7 @@ https://qinfendebingshuo.github.io/guanghulab/
### 🍊 桔子(光湖主控 · DEV-010) ### 🍊 桔子(光湖主控 · DEV-010)
1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/ 1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/docs/index.html
2. **选身份** → 下拉菜单选「🍊 桔子(光湖主控·DEV-010)」 2. **选身份** → 下拉菜单选「🍊 桔子(光湖主控·DEV-010)」
3. **填 API 密钥** → 输入自己的 API Key 3. **填 API 密钥** → 输入自己的 API Key
4. **点「开始对话」** → 铸渊显示你当前模块进度,并开放指挥台 4. **点「开始对话」** → 铸渊显示你当前模块进度,并开放指挥台
@ -53,7 +53,7 @@ https://qinfendebingshuo.github.io/guanghulab/
### 👩‍💻 其他开发者(页页 / 燕樊 / 小草莓 / 花尔 等) ### 👩‍💻 其他开发者(页页 / 燕樊 / 小草莓 / 花尔 等)
1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/ 1. **打开链接** → https://qinfendebingshuo.github.io/guanghulab/docs/index.html
2. **选身份** → 下拉菜单选自己的名字 2. **选身份** → 下拉菜单选自己的名字
3. **填 API 密钥** → 填自己的 Key(没有的话点「演示模式」) 3. **填 API 密钥** → 填自己的 Key(没有的话点「演示模式」)
4. **点「开始对话」** → 铸渊显示你的当前任务状态,可以问问题 4. **点「开始对话」** → 铸渊显示你的当前任务状态,可以问问题
@ -80,7 +80,7 @@ https://qinfendebingshuo.github.io/guanghulab/
``` ```
铸渊聊天室入口 👇 铸渊聊天室入口 👇
https://qinfendebingshuo.github.io/guanghulab/ https://qinfendebingshuo.github.io/guanghulab/docs/index.html
打开后选择你的身份,填入 API Key 就能和铸渊说话了。 打开后选择你的身份,填入 API Key 就能和铸渊说话了。
``` ```

View File

@ -360,8 +360,11 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo
</div> </div>
<div class="sfg"> <div class="sfg">
<label>API 密钥</label> <label>API 密钥</label>
<input type="password" id="ck" placeholder="sk-…"> <div style="display:flex;gap:6px;align-items:center">
<small>🔒 只保存在浏览器 localStorage,不上传任何服务器</small> <input type="password" id="ck" placeholder="sk-…" style="flex:1">
<button type="button" onclick="clearKeyField()" style="white-space:nowrap;padding:6px 10px;font-size:12px;border-radius:6px;border:1px solid var(--bdr);background:var(--bg2);color:var(--dim);cursor:pointer" title="清空输入框,输入新密钥">清空重填</button>
</div>
<small id="ck-hint" style="color:var(--dim)">🔒 只保存在浏览器 localStorage,不上传任何服务器</small>
</div> </div>
<button class="sbtn2" onclick="saveSet()">💾 保存设置</button> <button class="sbtn2" onclick="saveSet()">💾 保存设置</button>
@ -689,6 +692,13 @@ function initSettingsPanel(){
document.getElementById('cp').value = pv; document.getElementById('cp').value = pv;
fillModels('cm', pv, A.mdl); fillModels('cm', pv, A.mdl);
document.getElementById('ck').value = A.key?KEY_MASK:''; document.getElementById('ck').value = A.key?KEY_MASK:'';
// Show last 4 chars of current key so user can verify they're changing to a new one
const hint = document.getElementById('ck-hint');
if(hint){
hint.textContent = A.key
? '🔒 当前 Key 末4位:…'+A.key.slice(-4)+' · 要换新 Key 请点「清空重填」再输入'
: '🔒 只保存在浏览器 localStorage,不上传任何服务器';
}
if(pv==='custom'){ if(pv==='custom'){
document.getElementById('cep-g').style.display='block'; document.getElementById('cep-g').style.display='block';
document.getElementById('cep').value = A.base; document.getElementById('cep').value = A.base;
@ -697,6 +707,13 @@ function initSettingsPanel(){
if(A.ghUser) document.getElementById('cghuser').value=A.ghUser; if(A.ghUser) document.getElementById('cghuser').value=A.ghUser;
} }
function clearKeyField(){
const el = document.getElementById('ck');
if(el){el.value='';el.focus();}
const hint = document.getElementById('ck-hint');
if(hint) hint.textContent = '✏️ 请输入新的 API 密钥,输入完成后点「保存设置」';
}
function saveSet(){ function saveSet(){
const pv = document.getElementById('cp').value; const pv = document.getElementById('cp').value;
const md = document.getElementById('cm').value; const md = document.getElementById('cm').value;
@ -924,8 +941,11 @@ async function streamReply(txt){
if(!res.ok){ if(!res.ok){
const provLabel = A.prov==='custom' ? A.base : (A.prov+'('+A.base+')'); const provLabel = A.prov==='custom' ? A.base : (A.prov+'('+A.base+')');
let em='['+provLabel+'] 返回错误 '+res.status; let em='['+provLabel+'] 返回错误 '+res.status;
let isAuthErr = (res.status===401||res.status===403);
try{const e=await res.json();em=e.error?.message||em;}catch(_){} try{const e=await res.json();em=e.error?.message||em;}catch(_){}
throw new Error(em); const err = new Error(em);
err.isAuth = isAuthErr;
throw err;
} }
let full=''; let full='';
const rdr=res.body.getReader(); const rdr=res.body.getReader();
@ -951,7 +971,14 @@ async function streamReply(txt){
A.msgs.push({role:'assistant',content:full}); A.msgs.push({role:'assistant',content:full});
addCopyBtns(el); addCopyBtns(el);
}catch(e){ }catch(e){
el.innerHTML='<span class="err">⚠️ '+esc(e.message)+'</span><br><small style="color:var(--dim)">请检查 API 密钥和网络连接,或在 ⚙️ 设置中更换模型。</small>'; if(e.isAuth){
el.innerHTML='<span class="err">🔑 API 密钥认证失败</span>'
+'<br><small style="color:var(--dim)">'+esc(e.message)+'</small>'
+'<br><button onclick="openPanel(\'sp2\')" style="margin-top:8px;padding:6px 14px;border-radius:6px;border:none;background:var(--accent);color:#fff;cursor:pointer;font-size:13px">⚙️ 立即更新 API 密钥</button>'
+'<br><small style="color:var(--dim);display:block;margin-top:6px">打开设置 → 点「清空重填」→ 输入新密钥 → 保存</small>';
} else {
el.innerHTML='<span class="err">⚠️ '+esc(e.message)+'</span><br><small style="color:var(--dim)">请检查 API 密钥和网络连接,或在 ⚙️ 设置中更换模型。</small>';
}
A.msgs.pop(); A.msgs.pop();
}finally{ }finally{
A.streaming=false; updSendBtn(); scrollB(); A.streaming=false; updSendBtn(); scrollB();
@ -1179,7 +1206,9 @@ function closeP(){
// ═══════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════
// COPY URL (share link) // COPY URL (share link)
// ═══════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════
const CHAT_URL = 'https://' + REPO.split('/')[0] + '.github.io/' + REPO.split('/')[1] + '/'; // Auto-detect the real URL so the share link is always correct
// regardless of whether Pages serves from docs/ or repo root.
const CHAT_URL = window.location.origin + window.location.pathname;
function showCopyFeedback(success){ function showCopyFeedback(success){
const btn=document.querySelector('.copy-url-btn'); const btn=document.querySelector('.copy-url-btn');