@@ -165,12 +165,30 @@ $("#logoutBtn").onclick = async () => {
165165const PLATE = { newapi : "NA" , "newapi-key" : "KEY" , sub2api : "S2" , "sub2api-password" : "S2" } ;
166166const CH_PLATE = { telegram : "TG" , dingtalk : "DT" , wecom : "WC" , feishu : "FS" , bark : "BK" , ntfy : "NF" , serverchan : "SC" , resend : "RS" , smtp : "SM" , webhook : "WH" } ;
167167
168+ // 站点卡片里的迷你余额走势(近 48 小时):陡降 = 消耗快,平线 = 闲置,跳升 = 充值
169+ function sparkSvg ( pts ) {
170+ if ( ! pts || pts . length < 2 ) return "" ;
171+ const W = 170 , H = 30 , P = 3 ;
172+ const t0 = pts [ 0 ] [ 0 ] , t1 = pts [ pts . length - 1 ] [ 0 ] ;
173+ let min = Infinity , max = - Infinity ;
174+ for ( const [ , v ] of pts ) { if ( v < min ) min = v ; if ( v > max ) max = v ; }
175+ if ( max - min < 1e-9 ) { min -= 1 ; max += 1 ; } // 余额没变化时画一条居中的平线
176+ const x = ( t ) => P + ( ( t - t0 ) / ( t1 - t0 || 1 ) ) * ( W - 2 * P ) ;
177+ const y = ( v ) => P + ( 1 - ( v - min ) / ( max - min ) ) * ( H - 2 * P ) ;
178+ const line = pts . map ( ( p , i ) => `${ i ? "L" : "M" } ${ x ( p [ 0 ] ) . toFixed ( 1 ) } ,${ y ( p [ 1 ] ) . toFixed ( 1 ) } ` ) . join ( "" ) ;
179+ const area = `${ line } L${ x ( t1 ) . toFixed ( 1 ) } ,${ H - P } L${ x ( t0 ) . toFixed ( 1 ) } ,${ H - P } Z` ;
180+ const last = pts [ pts . length - 1 ] ;
181+ return `<svg class="spark" viewBox="0 0 ${ W } ${ H } " aria-hidden="true">
182+ <path class="spark-area" d="${ area } "/><path class="spark-line" d="${ line } "/>
183+ <circle class="spark-dot" cx="${ x ( last [ 0 ] ) . toFixed ( 1 ) } " cy="${ y ( last [ 1 ] ) . toFixed ( 1 ) } " r="2.5"/>
184+ </svg>` ;
185+ }
186+
168187function stationRow ( s ) {
169188 const st = statusOf ( s ) ;
170189 const b = s . balance ;
171190 const rate = rateOf ( s ) ;
172191 const cls = st === "danger" || st === "error" ? "danger" : st === "warn" ? "warn" : "" ;
173- const usedPct = b && b . ok && b . total > 0 ? Math . min ( 100 , Math . round ( ( b . used / b . total ) * 100 ) ) : 0 ;
174192 const amount = b && b . ok ? cny ( b . remaining * rate ) : "—" ;
175193 let meta ;
176194 if ( b && b . ok ) {
@@ -187,8 +205,9 @@ function stationRow(s) {
187205 } else {
188206 meta = `${ esc ( typeLabel ( s . type ) ) } · 尚未查询` ;
189207 }
190- const bar = b && b . ok
191- ? `<div class="st-bar"><div class="progress"><i class="${ cls } " style="width:${ usedPct } %"></i></div><span class="st-usage">已用 ${ cny ( b . used * rate ) } / ${ cny ( b . total * rate ) } </span></div>`
208+ const spark = sparkSvg ( s . spark ) ;
209+ const bar = b && b . ok && spark
210+ ? `<div class="st-bar" title="近 48 小时余额走势">${ spark } <span class="st-usage">近 48h 余额</span></div>`
192211 : "" ;
193212 const eta = etaText ( s . prediction , rate ) ;
194213 const pieces = [ ] ;
0 commit comments