feat: OCG router proxy — quota-aware 6-key routing
This commit is contained in:
@@ -462,6 +462,50 @@ document.getElementById('rdp-status-txt').textContent=fOn?'Connected':e4.rdp_ena
|
||||
if(cards)cards.innerHTML=html;
|
||||
}
|
||||
}catch(e5){}
|
||||
|
||||
/* --- OCG Router Proxy section --- */
|
||||
var pr=document.getElementById('proxy-router-section');
|
||||
if(!pr){
|
||||
pr=document.createElement('div');pr.id='proxy-router-section';pr.className='ps';pr.style.marginTop='16px';
|
||||
pr.innerHTML='<h2>OCG 路由代理<span class="help-btn" onclick="showModuleHelp(\'ocg_router\',\'human\')" title="使用说明">?</span><span class="help-btn ai" onclick="showModuleHelp(\'ocg_router\',\'ai\')" title="AI Spec">\u00a7</span></h2>'
|
||||
+'<div id="proxy-status-line" style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:10px;font-size:18px"></div>'
|
||||
+'<div id="proxy-pool" style="display:flex;flex-wrap:wrap;gap:6px"></div>';
|
||||
ci.appendChild(pr);
|
||||
}
|
||||
try{
|
||||
var prr=await fetch('/api/proxy/status');var prd=await prr.json();
|
||||
var pl=document.getElementById('proxy-status-line');
|
||||
var pp=document.getElementById('proxy-pool');
|
||||
if(!prd.ok||prd.proxy_running===false){
|
||||
if(pl)pl.innerHTML='<span style="color:var(--red)">\u2717 代理未运行</span>';
|
||||
if(pp)pp.innerHTML='<span style="color:var(--dim);font-size:18px">'+esc(prd.error||'无法连接 :19878')+'</span>';
|
||||
}else{
|
||||
if(pl)pl.innerHTML='<span style="color:var(--green);font-weight:600">当前路由: '+esc(prd.current_key||'—')+'</span>'
|
||||
+'<span style="color:var(--dim)">'+prd.total_requests+' 请求</span>'
|
||||
+'<span style="color:var(--dim)">'+prd.pool_healthy+'/'+prd.pool_size+' healthy</span>';
|
||||
if(pp){
|
||||
var ph='';
|
||||
for(var i=0;i<prd.pool.length;i++){
|
||||
var k=prd.pool[i];
|
||||
var mp=k.monthly_pct!=null?k.monthly_pct:0;
|
||||
var wp=k.weekly_pct!=null?k.weekly_pct:0;
|
||||
var ok=k.healthy&&!k.in_cooldown;
|
||||
var edge=ok?'var(--green)':'var(--red)';
|
||||
var bg=ok?'var(--card)':(k.in_cooldown?'rgba(251,140,0,.1)':'rgba(229,57,53,.06)');
|
||||
ph+='<div style="background:'+bg+';border:1px solid '+edge+';border-radius:6px;padding:6px 10px;min-width:120px;font-size:17px">'
|
||||
+'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:2px">'
|
||||
+'<strong style="font-size:16px">'+esc(k.key_id||'?')+'</strong>'
|
||||
+(k.hits>0?'<span style="font-size:14px;color:var(--accent)">'+k.hits+' hits</span>':'')
|
||||
+'</div>'
|
||||
+'<div style="font-size:14px;color:var(--dim)">M '+mp+'% \u00b7 W '+wp+'%</div>'
|
||||
+(k.in_cooldown?'<div style="font-size:13px;color:var(--yellow);margin-top:1px">冷却中</div>':'')
|
||||
+(k.error?'<div style="font-size:13px;color:var(--red);margin-top:1px">\u2717 '+esc(k.error)+'</div>':'')
|
||||
+'</div>';
|
||||
}
|
||||
pp.innerHTML=ph;
|
||||
}
|
||||
}
|
||||
}catch(prE){}
|
||||
}catch(e){}
|
||||
}
|
||||
function _fmtCountdown(sec){
|
||||
|
||||
Reference in New Issue
Block a user