@wendongfly/myhi 1.0.56 → 1.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.html +45 -5
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -215,6 +215,7 @@
|
|
|
215
215
|
<button class="top-btn" onclick="goBack()" title="返回">
|
|
216
216
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
|
|
217
217
|
</button>
|
|
218
|
+
<button class="top-btn" onclick="showUsage()" title="用量" style="font-size:0.7rem;color:var(--muted)">用量</button>
|
|
218
219
|
<button class="top-btn" id="logout-btn" onclick="doLogout()" title="退出" style="display:none;color:#f0883e">
|
|
219
220
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
|
220
221
|
</button>
|
|
@@ -223,14 +224,14 @@
|
|
|
223
224
|
<div id="status-bar">
|
|
224
225
|
<span class="sb-item" id="work-status"><span class="sb-dot idle"></span> 空闲</span>
|
|
225
226
|
<span id="mode-badge" onclick="switchMode()">默认</span>
|
|
226
|
-
<span id="control-badge" class="readonly"
|
|
227
|
+
<span id="control-badge" class="readonly" style="display:none">只读</span>
|
|
227
228
|
<span id="viewer-count" class="sb-item"></span>
|
|
228
229
|
</div>
|
|
229
230
|
|
|
230
231
|
<div id="chat-area"></div>
|
|
231
232
|
|
|
232
233
|
<div id="input-area">
|
|
233
|
-
<div id="readonly-overlay"
|
|
234
|
+
<div id="readonly-overlay" style="display:none"></div>
|
|
234
235
|
<div id="input-box">
|
|
235
236
|
<div id="img-preview">
|
|
236
237
|
<img id="img-preview-thumb" src="" alt="">
|
|
@@ -335,6 +336,45 @@
|
|
|
335
336
|
fetch('/api/me').then(r => r.json()).then(data => {
|
|
336
337
|
if (data.exclusive || data.hasUsers) document.getElementById('logout-btn').style.display = '';
|
|
337
338
|
}).catch(() => {});
|
|
339
|
+
window.showUsage = async () => {
|
|
340
|
+
try {
|
|
341
|
+
const res = await fetch('/api/usage');
|
|
342
|
+
const data = await res.json();
|
|
343
|
+
let html = '<div style="padding:1.25rem;max-width:500px">';
|
|
344
|
+
html += '<h3 style="margin:0 0 1rem;font-size:1rem">Claude 用量统计</h3>';
|
|
345
|
+
if (data.rateLimit) {
|
|
346
|
+
const rl = data.rateLimit;
|
|
347
|
+
const remaining = Math.max(0, Math.ceil((new Date(rl.resetsAt * 1000) - Date.now()) / 60000));
|
|
348
|
+
html += '<div style="margin-bottom:1rem;padding:0.8rem;background:var(--bg);border-radius:8px">';
|
|
349
|
+
html += '<div style="font-size:0.85rem;font-weight:600;margin-bottom:0.4rem">5小时窗口</div>';
|
|
350
|
+
html += `<div style="font-size:0.8rem;color:var(--muted)">状态: ${rl.status === 'allowed' ? '✓ 正常' : '⚠ 受限'} 重置: ${remaining}分钟后</div></div>`;
|
|
351
|
+
}
|
|
352
|
+
if (data.sevenDay) {
|
|
353
|
+
const s = data.sevenDay;
|
|
354
|
+
html += '<div style="margin-bottom:1rem;padding:0.8rem;background:var(--bg);border-radius:8px">';
|
|
355
|
+
html += '<div style="font-size:0.85rem;font-weight:600;margin-bottom:0.4rem">近7天</div>';
|
|
356
|
+
html += `<div style="font-size:0.8rem;color:var(--muted)">消息: ${s.messageCount.toLocaleString()} 会话: ${s.sessionCount} 工具: ${s.toolCallCount.toLocaleString()}</div></div>`;
|
|
357
|
+
}
|
|
358
|
+
if (data.activeSessions?.length) {
|
|
359
|
+
html += '<div style="margin-bottom:1rem;padding:0.8rem;background:var(--bg);border-radius:8px">';
|
|
360
|
+
html += '<div style="font-size:0.85rem;font-weight:600;margin-bottom:0.4rem">当前会话</div>';
|
|
361
|
+
for (const s of data.activeSessions) {
|
|
362
|
+
if (!s.usage) continue;
|
|
363
|
+
html += `<div style="font-size:0.8rem;color:var(--muted)">${s.title}: ${s.usage.queryCount}次, $${s.usage.totalCostUSD.toFixed(4)}</div>`;
|
|
364
|
+
}
|
|
365
|
+
html += '</div>';
|
|
366
|
+
}
|
|
367
|
+
html += '<button onclick="this.parentElement.parentElement.remove()" style="margin-top:0.5rem;width:100%;padding:0.6rem;background:var(--accent);color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:0.85rem">关闭</button></div>';
|
|
368
|
+
const overlay = document.createElement('div');
|
|
369
|
+
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:999;display:flex;align-items:center;justify-content:center';
|
|
370
|
+
overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
|
|
371
|
+
const box = document.createElement('div');
|
|
372
|
+
box.style.cssText = 'background:var(--surface);border-radius:16px;max-height:80vh;overflow-y:auto;width:90%;max-width:400px';
|
|
373
|
+
box.innerHTML = html;
|
|
374
|
+
overlay.appendChild(box);
|
|
375
|
+
document.body.appendChild(overlay);
|
|
376
|
+
} catch (err) { alert('获取用量失败: ' + err.message); }
|
|
377
|
+
};
|
|
338
378
|
window.doLogout = () => {
|
|
339
379
|
if (!confirm('确定退出登录?当前所有会话将被关闭。')) return;
|
|
340
380
|
fetch('/logout', { method: 'POST' }).then(() => { location.href = '/login'; });
|
|
@@ -1314,7 +1354,7 @@
|
|
|
1314
1354
|
};
|
|
1315
1355
|
function selectModel(m) {
|
|
1316
1356
|
closeModelSheet();
|
|
1317
|
-
if (!isController) { addStatusMessage('
|
|
1357
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1318
1358
|
if (currentSession?.mode === 'agent') {
|
|
1319
1359
|
// Agent 模式:通过命令设置
|
|
1320
1360
|
cmdInput.value = '/model ' + m.id;
|
|
@@ -1334,7 +1374,7 @@
|
|
|
1334
1374
|
|
|
1335
1375
|
// ── 恢复会话 ──────────────────────────────────
|
|
1336
1376
|
window.openResumeSheet = async function() {
|
|
1337
|
-
if (!isController) { addStatusMessage('
|
|
1377
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1338
1378
|
const list = document.getElementById('resume-list');
|
|
1339
1379
|
list.innerHTML = '<div style="text-align:center;padding:1rem;color:#8b949e">加载中...</div>';
|
|
1340
1380
|
document.getElementById('resume-sheet').classList.add('open');
|
|
@@ -1382,7 +1422,7 @@
|
|
|
1382
1422
|
|
|
1383
1423
|
// ── 压缩对话 ──────────────────────────────────
|
|
1384
1424
|
window.doCompact = function() {
|
|
1385
|
-
if (!isController) { addStatusMessage('
|
|
1425
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1386
1426
|
if (currentSession?.mode === 'agent') {
|
|
1387
1427
|
cmdInput.value = '/compact';
|
|
1388
1428
|
sendCommand();
|