feat: WeChat QR code + status inline in Platform tab
wechat_bridge entry now shows: - status text (已登录Xh / 已掉线Xh) via s.message - inline QR code with 5min expiry + refresh button when logged out - refreshWechatQR() fetches latest QR on demand (no polling)
This commit is contained in:
@@ -318,7 +318,31 @@ async function fI(){
|
||||
var h='';
|
||||
try{var r=await fetch('/api/platform'),d=await r.json();
|
||||
h+='<div class="ps"><h2>Platform<span class="help-btn" onclick="showModuleHelp(\'infra\',\'human\')" title="使用说明">?</span><span class="help-btn ai" onclick="showModuleHelp(\'infra\',\'ai\')" title="AI Spec">§</span></h2><div class="psv">';
|
||||
for(var i=0;i<d.length;i++){var s=d[i];h+='<div class="i"><span class="d '+(s.status==='running'?'ok':'stopped')+'"></span><span class="sn">'+esc(s.name)+'</span><span class="help-btn" onclick="showModuleHelp(\''+s.id+'\',\'human\')" title="使用说明">?</span><span class="help-btn ai" onclick="showModuleHelp(\''+s.id+'\',\'ai\')" title="AI Spec">§</span></div>';}
|
||||
for(var i=0;i<d.length;i++){var s=d[i];
|
||||
var dc='stopped',ds='',dt='';
|
||||
if(s.status==='running'){dc='ok';dt=s.message?' <span style=color:var(--green)>'+esc(s.message)+'</span>':'';}
|
||||
else if(s.status==='logged_out'){dc='ok';ds='background:var(--yellow)';dt=' <span style=color:var(--yellow)>'+esc(s.message||'\u9700\u626b\u7801')+'</span>';}
|
||||
h+='<div class="i"><span class="d '+dc+'"'+(ds?' style='+ds:'')+'></span><span class="sn">'+esc(s.name)+dt+'</span><span class="help-btn" onclick="showModuleHelp(\''+s.id+'\',\'human\')" title="\u4f7f\u7528\u8bf4\u660e">?</span><span class="help-btn ai" onclick="showModuleHelp(\''+s.id+'\',\'ai\')" title="AI Spec">\u00a7</span></div>';
|
||||
if(s.id==='wechat_bridge'&&s.status==='logged_out'&&s.qr_url){
|
||||
h+='<div style="margin:0 0 10px 18px;padding:12px 16px;background:#1a1400;border:1px solid var(--yellow);border-radius:8px;display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap">';
|
||||
h+='<div style=text-align:center;flex-shrink:0>';
|
||||
h+='<img id=wechat-qr-img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data='+encodeURIComponent(s.qr_url||'')+'" style="border:2px solid var(--yellow);border-radius:6px">';
|
||||
h+='<div id=wechat-qr-status style="margin-top:6px;font-size:14px;color:var(--dim)">';
|
||||
h+='<span id=wechat-qr-age>\u4e8c\u7ef4\u7801\u7ea65\u5206\u949f\u6709\u6548</span></div>';
|
||||
h+='<button id=wechat-qr-refresh class="btn r" style="margin-top:4px;font-size:14px;padding:3px 10px" onclick="refreshWechatQR()">\u5237\u65b0\u4e8c\u7ef4\u7801</button></div>';
|
||||
h+='<div style=flex:1;min-width:160px;font-size:14px;color:var(--dim)>';
|
||||
h+='<p style="margin:0 0 4px;color:var(--yellow);font-weight:600">\u83ab\u8377\u5fae\u4fe1\u9700\u8981\u626b\u7801\u767b\u5f55</p>';
|
||||
h+='<p style=margin:0;line-height:1.5>'+esc(s.message||'')+'\u3002\u7528\u5fae\u4fe1\u626b\u63cf\u5de6\u4fa7\u4e8c\u7ef4\u7801\u91cd\u65b0\u767b\u5f55\u3002</p>';
|
||||
h+='<p style=margin-top:4px>\u94fe\u63a5: <code style=word-break:break-all;font-size:13px>'+esc(s.qr_url||'')+'</code></p>';
|
||||
h+='</div></div>';
|
||||
setTimeout(function(){
|
||||
var el=document.getElementById('wechat-qr-age');
|
||||
if(el)el.innerHTML='<span style=color:var(--red)>\u4e8c\u7ef4\u7801\u5df2\u8fc7\u671f</span>';
|
||||
var btn=document.getElementById('wechat-qr-refresh');
|
||||
if(btn)btn.textContent='\u5df2\u8fc7\u671f\uff0c\u70b9\u51fb\u5237\u65b0';
|
||||
},300000);
|
||||
}
|
||||
}
|
||||
try{var r2=await fetch('/api/ejabberd'),ej=await r2.json();var ejA=ej.alive||ej.xmpp_bot_connected;
|
||||
h+='<div class="i"><span class="d '+(ejA?'ok':'stopped')+'"></span><span class="sn">Ejabberd XMPP</span><span class="help-btn" onclick="showModuleHelp(\'ejabberd\',\'human\')" title="使用说明">?</span><span class="help-btn ai" onclick="showModuleHelp(\'ejabberd\',\'ai\')" title="AI Spec">§</span></div>';
|
||||
}catch(ejErr){}
|
||||
|
||||
Reference in New Issue
Block a user