feat(mmp): 领取人ID/模块版本检测,并修正状态条误报红
展示 receiverId 与 activityPoolId;检测 Hook 是否最新;按真实时间排序;有心跳与定时拉取时不再因久无新数据爆红。
This commit is contained in:
@@ -41,6 +41,14 @@
|
||||
padding: 7px 12px; border-radius: 6px; cursor: pointer; font-size: 13px;
|
||||
}
|
||||
.btn.primary { background: #ea580c; border-color: #ea580c; color: #fff; font-weight: 600; }
|
||||
.conn-bar {
|
||||
background: #1f2937; color: #e5e7eb; padding: 8px 16px; font-size: 12px;
|
||||
line-height: 1.45; flex-shrink: 0; border-bottom: 1px solid #111827;
|
||||
}
|
||||
.conn-bar.ok { background: #064e3b; color: #d1fae5; }
|
||||
.conn-bar.bad { background: #7f1d1d; color: #fee2e2; }
|
||||
.conn-bar.warn { background: #78350f; color: #fef3c7; }
|
||||
.uid { display: block; font-size: 11px; color: var(--muted); font-weight: 500; margin-top: 2px; }
|
||||
.toolbar {
|
||||
background: var(--panel); border-bottom: 1px solid var(--line);
|
||||
padding: 10px 16px; display: grid; gap: 8px; flex-shrink: 0;
|
||||
@@ -184,6 +192,7 @@
|
||||
<button class="btn" onclick="loadData()">刷新</button>
|
||||
<button class="btn primary" onclick="clearAll()">清空</button>
|
||||
</header>
|
||||
<div class="conn-bar warn" id="connBar">模块检测中…</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="row">
|
||||
@@ -223,6 +232,7 @@
|
||||
<input type="number" id="cfgPagePoll" min="500" max="30000" step="100" />
|
||||
</label>
|
||||
<label class="check"><input type="checkbox" id="cfgOpenHistory" /> 无模板时自动打开历史页</label>
|
||||
<label class="check"><input type="checkbox" id="cfgBounceHistory" /> 检测不到连接时:自动进历史页再返回(重建连接)</label>
|
||||
</div>
|
||||
<div class="settings-actions">
|
||||
<button type="button" class="chip" onclick="applyPreset('fast')">极速</button>
|
||||
@@ -267,7 +277,7 @@
|
||||
</div>
|
||||
<div class="section">领取排行</div>
|
||||
<table>
|
||||
<thead><tr><th class="rank">#</th><th>昵称</th><th>金额</th><th>时间</th></tr></thead>
|
||||
<thead><tr><th class="rank">#</th><th>昵称 / ID</th><th>金额</th><th>时间</th></tr></thead>
|
||||
<tbody id="board"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -277,26 +287,28 @@
|
||||
<script>
|
||||
let packets = [], activeId = null, pagePollTimer = null;
|
||||
let statusFilter = 'all', timeFilter = 'all', keyword = '';
|
||||
let settings = { historyCooldownSec: 8, detailCooldownSec: 8, dedupSec: 3, detailGapMs: 80, pagePollMs: 1000, openHistoryIfNoTemplate: true };
|
||||
let settings = { historyCooldownSec: 8, detailCooldownSec: 8, dedupSec: 3, detailGapMs: 80, pagePollMs: 1000, openHistoryIfNoTemplate: true, autoBounceHistoryOnDisconnect: true };
|
||||
|
||||
function toggleSettings(){ document.getElementById('settingsPanel').classList.toggle('open'); }
|
||||
function fillSettingsForm(){
|
||||
cfgHistory.value = settings.historyCooldownSec; cfgDetail.value = settings.detailCooldownSec;
|
||||
cfgDedup.value = settings.dedupSec; cfgGap.value = settings.detailGapMs;
|
||||
cfgPagePoll.value = settings.pagePollMs; cfgOpenHistory.checked = !!settings.openHistoryIfNoTemplate;
|
||||
cfgBounceHistory.checked = settings.autoBounceHistoryOnDisconnect !== false;
|
||||
cfgHint.textContent = '刷新: 历史' + settings.historyCooldownSec + 's / 详情' + settings.detailCooldownSec + 's';
|
||||
}
|
||||
function readSettingsForm(){
|
||||
return {
|
||||
historyCooldownSec: Number(cfgHistory.value), detailCooldownSec: Number(cfgDetail.value),
|
||||
dedupSec: Number(cfgDedup.value), detailGapMs: Number(cfgGap.value),
|
||||
pagePollMs: Number(cfgPagePoll.value), openHistoryIfNoTemplate: cfgOpenHistory.checked
|
||||
pagePollMs: Number(cfgPagePoll.value), openHistoryIfNoTemplate: cfgOpenHistory.checked,
|
||||
autoBounceHistoryOnDisconnect: cfgBounceHistory.checked
|
||||
};
|
||||
}
|
||||
function applyPreset(name){
|
||||
if (name==='fast') settings={historyCooldownSec:5,detailCooldownSec:5,dedupSec:2,detailGapMs:50,pagePollMs:800,openHistoryIfNoTemplate:true};
|
||||
else if (name==='slow') settings={historyCooldownSec:30,detailCooldownSec:45,dedupSec:15,detailGapMs:200,pagePollMs:3000,openHistoryIfNoTemplate:true};
|
||||
else settings={historyCooldownSec:8,detailCooldownSec:8,dedupSec:3,detailGapMs:80,pagePollMs:1000,openHistoryIfNoTemplate:true};
|
||||
if (name==='fast') settings={historyCooldownSec:5,detailCooldownSec:5,dedupSec:2,detailGapMs:50,pagePollMs:800,openHistoryIfNoTemplate:true,autoBounceHistoryOnDisconnect:true};
|
||||
else if (name==='slow') settings={historyCooldownSec:30,detailCooldownSec:45,dedupSec:15,detailGapMs:200,pagePollMs:3000,openHistoryIfNoTemplate:true,autoBounceHistoryOnDisconnect:true};
|
||||
else settings={historyCooldownSec:8,detailCooldownSec:8,dedupSec:3,detailGapMs:80,pagePollMs:1000,openHistoryIfNoTemplate:true,autoBounceHistoryOnDisconnect:true};
|
||||
fillSettingsForm();
|
||||
}
|
||||
async function loadSettings(){ settings = await (await fetch('/api/mmp/settings')).json(); fillSettingsForm(); restartPagePoll(); }
|
||||
@@ -348,7 +360,7 @@
|
||||
if(statusFilter==='done'&&!p.finished) return false;
|
||||
if(!inTimeRange(p)) return false;
|
||||
if(!keyword) return true;
|
||||
const blob=[p.packetId,p.sender,p.title,p.group,p.total,p.bestNick,p.worstNick,...(p.leaderboard||[]).map(r=>r.nickname)].join(' ').toLowerCase();
|
||||
const blob=[p.packetId,p.sender,p.title,p.group,p.total,p.bestNick,p.worstNick,...(p.leaderboard||[]).map(r=>[r.nickname,r.userId,r.poolId].join(' '))].join(' ').toLowerCase();
|
||||
return blob.indexOf(keyword)>=0;
|
||||
});
|
||||
}
|
||||
@@ -362,11 +374,28 @@
|
||||
}
|
||||
|
||||
async function loadData(){
|
||||
packets = await (await fetch('/api/mmp')).json();
|
||||
const [pktRes, stRes] = await Promise.all([
|
||||
fetch('/api/mmp'),
|
||||
fetch('/api/mmp/status')
|
||||
]);
|
||||
packets = await pktRes.json();
|
||||
updated.textContent = '更新 ' + new Date().toLocaleTimeString();
|
||||
try {
|
||||
const st = await stRes.json();
|
||||
renderConnBar(st);
|
||||
} catch (e) {
|
||||
renderConnBar({ text: '模块状态不可用', ok: false });
|
||||
}
|
||||
renderList();
|
||||
}
|
||||
|
||||
function renderConnBar(st){
|
||||
const el = document.getElementById('connBar');
|
||||
if (!el) return;
|
||||
el.textContent = (st && st.text) ? st.text : '模块状态未知';
|
||||
el.className = 'conn-bar ' + (st && st.ok ? 'ok' : (st && st.liveAt ? 'bad' : 'warn'));
|
||||
}
|
||||
|
||||
function renderList(){
|
||||
const view=filteredPackets();
|
||||
pktCount.textContent = view.length + '/' + packets.length + ' 个';
|
||||
@@ -442,9 +471,12 @@
|
||||
let nick=esc(row.nickname);
|
||||
if(isBest) nick += '<span class="tag-inline best">最高</span>';
|
||||
if(isWorst) nick += '<span class="tag-inline worst">最低</span>';
|
||||
let nickHtml=`<div>${nick}</div>`;
|
||||
if(row.userId) nickHtml += `<span class="uid">用户ID ${esc(row.userId)}</span>`;
|
||||
if(row.poolId) nickHtml += `<span class="uid">领取ID ${esc(row.poolId)}</span>`;
|
||||
tr.innerHTML=`
|
||||
<td class="rank">${row.rank}</td>
|
||||
<td class="nick">${nick}</td>
|
||||
<td class="nick">${nickHtml}</td>
|
||||
<td class="amt">${esc(row.amountText || money(row.amount))}</td>
|
||||
<td>${esc(row.claimTime || '-')}</td>`;
|
||||
board.appendChild(tr);
|
||||
|
||||
Reference in New Issue
Block a user