-
-
已注册成员 · 统一登录 进入代码域
-
- 已有账户?直接登录。新成员需管理员创建账号。
- 各仓库节点通过联邦令牌互连,
了解联邦接入。
-
-
+
+
+
+
+
+
+
+
+
@@ -402,10 +438,64 @@ body{
/* ── Clock ── */
(function t(){const e=document.getElementById('feed-now-time');if(e)e.textContent=new Date().toLocaleTimeString('zh-CN',{hour:'2-digit',minute:'2-digit'});setTimeout(t,30000)})();
-/* ── Login ── */
-function login(){const u=document.getElementById('login-user').value.trim(),p=document.getElementById('login-pass').value;if(!u||!p){alert('请输入账号和密码');return}window.location.href='/code/user/login?redirect_to=/'+u}
+/* ── 登录系统 ── */
+async function handleLogin(){
+ const u=document.getElementById('login-user').value.trim(),p=document.getElementById('login-pass').value;
+ if(!u||!p){showLoginError('请输入账号和密码');return}
+ showLoginLoading(true);
+ try{
+ const r=await fetch('/api/verify',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({user:u,password:p})});
+ const d=await r.json();
+ if(d.ok){
+ localStorage.setItem('current_user',d.username);
+ localStorage.setItem('is_admin',d.is_admin);
+ localStorage.setItem('logged_in','true');
+ localStorage.setItem('login_time',Date.now().toString());
+ showLoggedIn(d.username);
+ document.getElementById('login-pass').value='';
+ }else{
+ showLoginError(d.error||'登录失败');
+ }
+ }catch(e){showLoginError('连接失败')}
+ showLoginLoading(false);
+}
+function showLoginError(msg){const e=document.getElementById('login-error');e.textContent=msg;e.style.display='block';setTimeout(()=>e.style.display='none',3000)}
+function showLoginLoading(v){document.getElementById('login-loading').style.display=v?'block':'none';document.getElementById('login-btn').disabled=v}
-/* ── Training ── */
+function showLoggedIn(username){
+ document.getElementById('login-bar').style.display='none';
+ document.getElementById('logged-in-bar').style.display='flex';
+ document.getElementById('user-name').textContent=username;
+ document.getElementById('user-avatar').textContent=username[0].toUpperCase();
+}
+function goToRepo(){
+ const u=localStorage.getItem('current_user');
+ window.location.href='/code/'+u;
+}
+function dismissRepo(){
+ // 已登录状态保持不变,关闭跳转提示
+}
+function logout(){
+ localStorage.removeItem('current_user');
+ localStorage.removeItem('is_admin');
+ localStorage.removeItem('logged_in');
+ localStorage.removeItem('login_time');
+ document.getElementById('logged-in-bar').style.display='none';
+ document.getElementById('login-bar').style.display='flex';
+ document.getElementById('login-user').value='';
+}
+
+// 页面加载时检查登录状态
+(function(){
+ const u=localStorage.getItem('current_user');
+ if(u&&localStorage.getItem('logged_in')==='true'){
+ showLoggedIn(u);
+ }
+})();
+
+// 重写 sendCardMsg 和 sendMsg 带上用户信息
+async function sendCardMsg(){const i=document.getElementById('card-chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-card-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='
'+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='
✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='
'+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='
连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
+async function sendMsg(){const i=document.getElementById('chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='
'+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='
✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='
'+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='
连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
async function upTr(){try{const r=await fetch('/training-status.json');if(!r.ok)return;const d=await r.json();if(d.step===undefined)return;const s=d.step||0,t=d.total||12243,p=Math.min(s/t*100,100);document.getElementById('train-step').textContent=s.toLocaleString()+' / '+t.toLocaleString();document.getElementById('train-pct').textContent=p.toFixed(1)+'%';document.getElementById('train-bar').style.width=p+'%';if(d.loss!==undefined)document.getElementById('train-loss').textContent=d.loss;const e=document.getElementById('train-eta');if(e)e.textContent='预计今日完成 · Step '+s.toLocaleString();const z=document.getElementById('persona-zhu-status');if(z)z.textContent='训练中 · '+p.toFixed(0)+'%';const tag=document.getElementById('status-tag');if(tag)tag.textContent='● 训练中 · Step '+s.toLocaleString()}catch(e){}}
setInterval(upTr,30000);upTr();
@@ -413,14 +503,9 @@ setInterval(upTr,30000);upTr();
async function connectNotion(){try{window.location.href='/api/notion/connect?user_key=default'}catch(e){alert('Notion 连接暂时不可用')}}
async function checkNt(){try{const r=await fetch('/api/notion/status');const d=await r.json();if(!d.ok)return;const b=document.getElementById('notion-body'),l=document.getElementById('notion-label');if(d.connected_users&&d.connected_users.length>0){const u=d.connected_users[0];l.textContent='✅ '+u.workspace;b.innerHTML='
✅ Notion 已连接
工作区: '+u.workspace+'
'}else{l.textContent='未连接';b.innerHTML='
连接 Notion 后,铸渊可读取和记录你的页面
✅ 按语言路径读取 · ✅ 新建页面 · ❌ 不编辑/删除现有
'}}catch(e){}}
setInterval(checkNt,15000);checkNt();
-
-/* ── Chat ── */
+/* ── 浮窗对话 ── */
let chatOpen=false;
function toggleChat(){chatOpen=!chatOpen;document.getElementById('chat-panel').classList.toggle('open')}
-async function sendMsg(){const i=document.getElementById('chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='
'+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='
✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='
'+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='
连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
-
-/* ── 页面中央对话 ── */
-async function sendCardMsg(){const i=document.getElementById('card-chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-card-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='
'+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='
✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='
'+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='
连接暂不可用
'}ms.scrollTop=ms.scrollHeight}