42 lines
6.2 KiB
HTML
42 lines
6.2 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}关注 — AlphaX Agent | Crypto{% endblock %}
|
||
{% block nav_links %}
|
||
<a class="sidebar-link" href="/app"><svg class="link-icon"><use href="#svg-dashboard"/></svg>看板</a>
|
||
<a class="sidebar-link" href="/sentiment"><svg class="link-icon"><use href="#svg-sentiment"/></svg>舆情</a>
|
||
<a class="sidebar-link" href="/subscription"><svg class="link-icon"><use href="#svg-subscribe"/></svg>订阅</a>
|
||
<a class="sidebar-link" href="/referral"><svg class="link-icon"><use href="#svg-referral"/></svg>推荐</a>
|
||
<div class="sidebar-section-label admin-link" style="display:none">研发</div>
|
||
<a class="sidebar-link admin-link" href="/pipeline" style="display:none"><svg class="link-icon"><use href="#svg-pipeline"/></svg>链路日志</a>
|
||
<a class="sidebar-link admin-link" href="/strategy" style="display:none"><svg class="link-icon"><use href="#svg-target"/></svg>策略</a>
|
||
<a class="sidebar-link admin-link" href="/iteration" style="display:none"><svg class="link-icon"><use href="#svg-iterate"/></svg>迭代</a>
|
||
<a class="sidebar-link admin-link" href="/admin.html" style="display:none"><svg class="link-icon"><use href="#svg-admin"/></svg>管理</a>
|
||
{% endblock %}
|
||
{% block extra_head_css %}
|
||
<style>
|
||
.shell{width:min(100% - 40px,1180px);margin:0 auto;padding:24px 0 48px}.page-head{margin-bottom:20px}.page-head h1{font-size:28px;letter-spacing:-.8px}.page-head p{color:var(--stone);font-size:14px;margin-top:4px}.grid{display:grid;grid-template-columns:1fr;gap:16px}.panel{border:1px solid var(--hairline-soft);background:var(--canvas);border-radius:var(--radius-xl);padding:18px}.panel h2{font-size:16px;margin-bottom:12px}.actions{display:flex;gap:8px;flex-wrap:wrap}.input{height:42px;border:1px solid var(--hairline-strong);border-radius:var(--radius-full);padding:0 14px;outline:none;min-width:220px}.btn{border:1px solid var(--hairline-strong);background:var(--canvas);border-radius:var(--radius-full);padding:9px 14px;font-size:13px;font-weight:700;cursor:pointer}.btn.primary{background:var(--primary);color:var(--on-primary);border-color:var(--primary)}.tokens{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}.token{display:inline-flex;align-items:center;gap:6px;background:var(--surface);border-radius:var(--radius-full);padding:6px 10px;font-size:13px;font-weight:800}.token button{border:0;background:transparent;color:var(--stone);cursor:pointer;font-weight:900}.watch-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:14px}.watch-card{border:1px solid var(--hairline-soft);border-radius:var(--radius-lg);padding:14px;background:var(--surface)}.watch-card b{font-size:16px}.meta{font-size:12px;color:var(--stone);margin-top:6px}.status{display:inline-flex;margin-top:8px;border-radius:var(--radius-full);padding:3px 8px;font-size:11px;font-weight:800}.status.buy{color:var(--green);background:var(--green-light)}.status.wait{color:var(--yellow-dark);background:var(--yellow-light)}.status.obs{color:var(--blue);background:rgba(66,98,255,.06)}.empty{color:var(--stone);font-size:13px;padding:12px 0}@media(max-width:820px){.watch-cards{grid-template-columns:1fr}.shell{width:min(100% - 24px,1180px);padding-top:16px}.actions .input{flex:1;min-width:160px}.btn{min-height:44px}}
|
||
</style>
|
||
{% endblock %}
|
||
{% block content %}
|
||
<div class="shell">
|
||
<div class="page-head"><h1>关注</h1><p>集中维护你关心的币种;看板里可以用“只看关注池”快速筛选。</p></div>
|
||
<div class="grid">
|
||
<section class="panel">
|
||
<h2>我的关注池</h2>
|
||
<div class="actions"><input class="input" id="symbolInput" placeholder="输入币种,如 ENS"><button class="btn primary" onclick="addSymbol()">加入关注</button><a class="btn" href="/app">回看板</a></div>
|
||
<div class="tokens" id="tokens"></div>
|
||
</section>
|
||
<section class="panel"><h2>关注池实时状态</h2><div class="watch-cards" id="watchCards"></div></section>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
{% block extra_script %}
|
||
<script>
|
||
var personalization={watchlist:[]};var active=[];
|
||
function norm(s){s=String(s||'').trim().toUpperCase();return s?(s.indexOf('/')>=0?s:s+'/USDT'):''}function base(s){return String(s||'').replace('/USDT','')}function priceDecimals(p){p=Math.abs(Number(p||0));if(p<=0)return 2;if(p<0.0001)return 8;if(p<0.001)return 7;if(p<0.01)return 6;if(p<0.1)return 5;if(p<1)return 4;if(p<10)return 3;return 2}function fmtPrice(p){p=Number(p||0);return p>0?('$'+p.toFixed(priceDecimals(p))):'--'}
|
||
async function loadAll(){try{var p=await fetch('/api/personalization');if(p.ok)personalization=await p.json()}catch(e){}try{active=await (await fetch('/api/recommendations/active?actionable_only=false&hours=12')).json()}catch(e){active=[]}render()}
|
||
function render(){var wl=personalization.watchlist||[];tokens.innerHTML=wl.length?wl.map(s=>'<span class="token">'+base(s)+'<button onclick="removeSymbol(\''+base(s)+'\')">×</button></span>').join(''):'<div class="empty">暂无关注币</div>';renderWatchCards(wl)}
|
||
function renderWatchCards(wl){var map={};active.forEach(x=>map[x.symbol]=x);watchCards.innerHTML=wl.length?wl.map(s=>{var x=map[s]||{};var st=x.execution_status==='buy_now'?'buy':x.execution_status==='wait_pullback'?'wait':'obs';var label=x.execution_status==='buy_now'?'入场窗口':x.execution_status==='wait_pullback'?'等回踩':x.symbol?'观察中':'暂无信号';return '<div class="watch-card"><b>'+base(s)+'</b><div class="meta">当前价 '+fmtPrice(x.current_price)+'</div><span class="status '+st+'">'+label+'</span><div class="meta">最后信号 '+(x.rec_time?fmtTime(x.rec_time):'--')+'</div></div>'}).join(''):'<div class="empty">先加入关注币,系统会自动显示它们的实时状态。</div>'}
|
||
async function addSymbol(){var s=norm(symbolInput.value);if(!s)return;await fetch('/api/watchlist',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({symbol:s})});symbolInput.value='';loadAll()}async function removeSymbol(s){await fetch('/api/watchlist/'+encodeURIComponent(s),{method:'DELETE'});loadAll()}function fmtTime(t){if(!t)return'--';var diff=(Date.now()-new Date(t).getTime())/1000;if(diff<60)return'刚刚';if(diff<3600)return Math.round(diff/60)+'分钟前';if(diff<86400)return Math.round(diff/3600)+'小时前';var d=new Date(t);return(d.getMonth()+1)+'/'+d.getDate()}loadAll();
|
||
</script>
|
||
{% endblock %}
|