misc: binance momentum, telegram, frontend updates
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
import{r as c,j as t,c as B,R as E}from"./client-DYDkQYN6.js";const w="https://www.binance.com/en/futures/";function M(){const[r,S]=c.useState([]),[h,g]=c.useState([]),[C,x]=c.useState("● 连接中..."),[v,u]=c.useState(!1),[i,y]=c.useState("change_abs"),[l,j]=c.useState("desc"),d=c.useRef(null),p=c.useCallback(()=>{const e=new EventSource("/events");d.current=e,e.addEventListener("connected",()=>{x("● 已连接"),u(!0)}),e.onmessage=a=>{try{const n=JSON.parse(a.data);switch(n.event){case"binance_momentum":S(n.data);break;case"binance_alert":g(s=>[n.data,...s].slice(0,200));break}}catch{}},e.onerror=()=>{x("● 已断开 (重连中...)"),u(!1),e.close(),setTimeout(p,3e3)}},[]);c.useEffect(()=>(p(),()=>{d.current&&d.current.close()}),[p]),c.useEffect(()=>{const a=setInterval(async()=>{try{const s=await(await fetch("/api/binance-alerts?limit=50")).json();s.alerts&&s.alerts.length>0&&g(_=>{const $=new Set(_.map(o=>o.timestamp)),N=[..._];for(const o of s.alerts)$.has(o.timestamp)||N.push(o);return N.slice(0,200)})}catch{}},1e4);return()=>clearInterval(a)},[]);const m=e=>{i===e?j(a=>a==="asc"?"desc":"asc"):(y(e),j("desc"))},f=[...r].sort((e,a)=>{let n,s;switch(i){case"coin":return n=e.coin,s=a.coin,l==="asc"?n.localeCompare(s):s.localeCompare(n);case"price":n=e.price||0,s=a.price||0;break;case"change_abs":n=Math.abs(e.change_pct)||0,s=Math.abs(a.change_pct)||0;break;case"change":n=e.change_pct||0,s=a.change_pct||0;break;default:return 0}return l==="asc"?n-s:s-n}),k=r.filter(e=>e.buffer_full).length,b=r.filter(e=>Math.abs(e.change_pct)>=10).length;return t.jsxs("div",{id:"bm-app",children:[t.jsxs("header",{children:[t.jsxs("div",{children:[t.jsx("h1",{children:"BN 1-Min Momentum Monitor"}),t.jsx("span",{className:"header-subtitle",children:"Binance 1分钟涨跌监控 | 阈值 ≥10%"})]}),t.jsxs("div",{className:"header-right",children:[t.jsxs("span",{className:"stat-badge",children:[r.length," coins"]}),t.jsxs("span",{className:"stat-badge",children:[k," ready"]}),b>0&&t.jsxs("span",{className:"stat-badge stat-alert",children:[b," alerting"]}),t.jsx("span",{className:v?"status-online":"status-offline",children:C})]})]}),h.length>0&&t.jsxs("section",{className:"card card-wide alert-section",children:[t.jsxs("h2",{children:["Alert History (",h.length,")"]}),t.jsx("div",{className:"alert-scroll",children:h.slice(0,50).map((e,a)=>{var n,s;return t.jsxs("div",{className:`alert-item alert-${e.direction}`,children:[t.jsx("span",{className:"alert-icon",children:e.direction==="up"?"🟢":"🔴"}),t.jsx("a",{href:`${w}${e.coin}USDT`,target:"_blank",rel:"noreferrer",className:"alert-coin",children:e.coin}),t.jsxs("span",{className:e.direction==="up"?"text-green":"text-red",children:[e.change_pct>=0?"+":"",(n=e.change_pct)==null?void 0:n.toFixed(2),"%"]}),t.jsxs("span",{className:"alert-price",children:["$",(s=e.price)==null?void 0:s.toFixed(4)]}),t.jsx("span",{className:"alert-time text-dim",children:new Date(e.timestamp).toLocaleTimeString()})]},a)})})]}),t.jsxs("section",{className:"card card-wide",children:[t.jsxs("h2",{children:["All Coins (",r.length,")"]}),t.jsx("div",{className:"table-wrap",style:{maxHeight:"calc(100vh - 200px)"},children:t.jsxs("table",{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsxs("th",{onClick:()=>m("coin"),style:{cursor:"pointer"},children:["Coin ",i==="coin"?l==="asc"?"▲":"▼":""]}),t.jsxs("th",{onClick:()=>m("price"),style:{cursor:"pointer"},children:["Price ",i==="price"?l==="asc"?"▲":"▼":""]}),t.jsxs("th",{onClick:()=>m("change_abs"),style:{cursor:"pointer"},children:["1m Change ",i==="change_abs"?l==="asc"?"▲":"▼":""]}),t.jsx("th",{children:"Bar"})]})}),t.jsxs("tbody",{children:[f.map(e=>{const a=e.buffer_full?e.change_pct>=10?"row-surge-up":e.change_pct<=-10?"row-surge-down":e.change_pct>0?"row-up":e.change_pct<0?"row-down":"":"row-warmup",n=Math.min(Math.abs(e.change_pct)/15*100,100),s=e.change_pct>=10?"bar-green":e.change_pct<=-10?"bar-red":e.change_pct>0?"bar-green-dim":"bar-red-dim";return t.jsxs("tr",{className:a,children:[t.jsxs("td",{children:[t.jsx("a",{href:`${w}${e.coin}USDT`,target:"_blank",rel:"noreferrer",className:"coin-link",children:e.coin}),!e.buffer_full&&t.jsx("span",{className:"warmup-badge",children:"···"})]}),t.jsx("td",{className:"text-right mono",children:e.price?`$${e.price.toFixed(4)}`:"-"}),t.jsx("td",{className:`text-right mono ${e.change_pct>=10?"text-green":e.change_pct<=-10?"text-red":e.change_pct>0?"text-green":e.change_pct<0?"text-red":"text-dim"}`,children:e.buffer_full?`${e.change_pct>=0?"+":""}${e.change_pct.toFixed(2)}%`:"warming..."}),t.jsx("td",{children:t.jsx("div",{className:"bar-track",children:t.jsx("div",{className:`bar-fill ${s}`,style:{width:`${n}%`}})})})]},e.coin)}),f.length===0&&t.jsx("tr",{children:t.jsx("td",{colSpan:4,className:"loading",children:"Waiting for data..."})})]})]})})]})]})}B.createRoot(document.getElementById("root")).render(t.jsx(E.StrictMode,{children:t.jsx(M,{})}));
|
||||
+1
@@ -0,0 +1 @@
|
||||
:root{--bg: #0d1117;--card: #161b22;--border: #30363d;--text: #c9d1d9;--text-dim: #8b949e;--accent: #58a6ff;--green: #3fb950;--red: #f85149;--yellow: #d29922}*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--text);font-size:14px;line-height:1.5;min-height:100vh}#bm-app{max-width:1200px;margin:0 auto;padding:16px}header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;background:var(--card);border:1px solid var(--border);border-radius:8px;margin-bottom:12px;flex-wrap:wrap;gap:8px}header h1{font-size:18px;font-weight:600}.header-subtitle{font-size:12px;color:var(--text-dim);margin-left:12px}.header-right{display:flex;align-items:center;gap:10px;font-size:13px}.stat-badge{background:#58a6ff1a;color:var(--accent);padding:2px 8px;border-radius:10px;font-size:12px;font-weight:500}.stat-alert{background:#f8514926;color:var(--red);animation:pulse 2s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.6}}.status-online{color:var(--green)}.status-offline{color:var(--red)}.card{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:12px;margin-bottom:12px}.card h2{font-size:14px;font-weight:600;color:var(--text-dim);margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--border)}.alert-scroll{display:flex;flex-wrap:wrap;gap:6px;max-height:120px;overflow-y:auto}.alert-item{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:4px;font-size:13px;font-variant-numeric:tabular-nums}.alert-up{background:#3fb95014}.alert-down{background:#f8514914}.alert-icon{font-size:14px}.alert-coin{color:var(--accent);text-decoration:none;font-weight:600;min-width:50px}.alert-coin:hover{text-decoration:underline}.alert-price{color:var(--text-dim);min-width:90px}.alert-time{font-size:11px}.table-wrap{overflow-x:auto;overflow-y:auto}table{width:100%;border-collapse:collapse;font-size:13px}th{text-align:left;padding:6px 8px;color:var(--text-dim);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:.5px;position:sticky;top:0;background:var(--card);border-bottom:1px solid var(--border);-webkit-user-select:none;user-select:none}th:hover{color:var(--accent)}td{padding:4px 8px;border-bottom:1px solid rgba(48,54,61,.5);white-space:nowrap}tr:hover td{background:#58a6ff0d}.coin-link{color:var(--accent);text-decoration:none;font-weight:600}.coin-link:hover{text-decoration:underline}.warmup-badge{font-size:10px;color:var(--text-dim);margin-left:6px}.row-warmup td{opacity:.45}.row-surge-up td{background:#3fb9501a!important}.row-surge-up:hover td{background:#3fb9502e!important}.row-surge-down td{background:#f851491a!important}.row-surge-down:hover td{background:#f851492e!important}.row-up td{background:#3fb95008}.row-down td{background:#f8514908}.bar-track{width:100px;height:6px;background:#30363d80;border-radius:3px;overflow:hidden}.bar-fill{height:100%;border-radius:3px;transition:width .3s ease}.bar-green{background:var(--green)}.bar-red{background:var(--red)}.bar-green-dim{background:#3fb95080}.bar-red-dim{background:#f8514980}.text-green{color:var(--green)}.text-red{color:var(--red)}.text-dim{color:var(--text-dim)}.text-right{text-align:right}.mono{font-variant-numeric:tabular-nums;font-family:SF Mono,Cascadia Code,monospace}.loading{text-align:center;color:var(--text-dim);padding:20px!important}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#484f58}@media (max-width: 768px){header{flex-direction:column}#bm-app{padding:8px}}
|
||||
+40
File diff suppressed because one or more lines are too long
-40
File diff suppressed because one or more lines are too long
-40
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user