Download center: copy code, online/offline status; remove client offline mode.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+24
-3
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import secrets
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
|
||||
from flask import (
|
||||
@@ -323,7 +324,8 @@ def register_routes(app: Flask) -> None:
|
||||
if u["role"] == "admin":
|
||||
acts = conn.execute(
|
||||
"""
|
||||
SELECT act.*, a.name AS account_name, m.name AS machine_name
|
||||
SELECT act.*, a.name AS account_name, m.name AS machine_name,
|
||||
m.last_seen_at AS machine_last_seen
|
||||
FROM activations act
|
||||
LEFT JOIN accounts a ON a.id = act.account_id
|
||||
LEFT JOIN machines m ON m.id = act.machine_id
|
||||
@@ -333,7 +335,8 @@ def register_routes(app: Flask) -> None:
|
||||
else:
|
||||
acts = conn.execute(
|
||||
"""
|
||||
SELECT act.*, a.name AS account_name, m.name AS machine_name
|
||||
SELECT act.*, a.name AS account_name, m.name AS machine_name,
|
||||
m.last_seen_at AS machine_last_seen
|
||||
FROM activations act
|
||||
LEFT JOIN accounts a ON a.id = act.account_id
|
||||
LEFT JOIN machines m ON m.id = act.machine_id
|
||||
@@ -342,7 +345,25 @@ def register_routes(app: Flask) -> None:
|
||||
""",
|
||||
(u.get("account_id"),),
|
||||
).fetchall()
|
||||
activations = [database.row_to_dict(r) for r in acts]
|
||||
activations = []
|
||||
now_ts = database.now()
|
||||
online_sec = 180 # 3 分钟内有心跳视为在线
|
||||
for r in acts:
|
||||
item = database.row_to_dict(r)
|
||||
last = item.get("machine_last_seen")
|
||||
if item.get("status") == "active" and last and (now_ts - float(last)) <= online_sec:
|
||||
item["online_label"] = "在线"
|
||||
item["online"] = True
|
||||
else:
|
||||
item["online_label"] = "离线"
|
||||
item["online"] = False
|
||||
try:
|
||||
item["created_at_fmt"] = datetime.fromtimestamp(float(item["created_at"])).strftime(
|
||||
"%Y-%m-%d %H:%M"
|
||||
)
|
||||
except (TypeError, ValueError, OSError):
|
||||
item["created_at_fmt"] = str(item.get("created_at") or "—")
|
||||
activations.append(item)
|
||||
exe_name = "黄金市价辅助.exe"
|
||||
exe_path = RELEASES_DIR / exe_name
|
||||
return render_template(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="grid cols-2">
|
||||
<div class="card">
|
||||
<h3>通用辅助包</h3>
|
||||
<p class="muted">所有机器下载同一 exe。首次启动输入激活码,绑定账户与机器标识。</p>
|
||||
<p class="muted">所有机器下载同一 exe。首次启动输入激活码,绑定账户与机器标识(须在线,不允许离线运行)。</p>
|
||||
{% if exe_ready %}
|
||||
<p><span class="tag green">已上传 {{ exe_name }}</span></p>
|
||||
<a class="btn" href="{{ url_for('download_file') }}">下载 exe</a>
|
||||
@@ -48,11 +48,21 @@
|
||||
<tbody>
|
||||
{% for a in activations %}
|
||||
<tr>
|
||||
<td><code>{{ a.code }}</code></td>
|
||||
<td>
|
||||
<code id="code-{{ loop.index }}">{{ a.code }}</code>
|
||||
<button type="button" class="btn secondary btn-copy" style="margin-left:8px;padding:4px 10px;font-size:12px"
|
||||
data-code="{{ a.code }}">复制</button>
|
||||
</td>
|
||||
<td>{{ a.account_name or a.account_id }}</td>
|
||||
<td>{{ a.machine_name or a.machine_id or '—' }}</td>
|
||||
<td><span class="tag {% if a.status=='active' %}green{% else %}gray{% endif %}">{{ a.status }}</span></td>
|
||||
<td class="muted">{{ a.created_at }}</td>
|
||||
<td>
|
||||
{% if a.online %}
|
||||
<span class="tag green">在线</span>
|
||||
{% else %}
|
||||
<span class="tag gray">离线</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="muted">{{ a.created_at_fmt }}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="5" class="muted">暂无激活码</td></tr>
|
||||
@@ -61,3 +71,27 @@
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.querySelectorAll('.btn-copy').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var code = btn.getAttribute('data-code') || '';
|
||||
function done(ok) {
|
||||
var old = btn.textContent;
|
||||
btn.textContent = ok ? '已复制' : '失败';
|
||||
setTimeout(function () { btn.textContent = old; }, 1200);
|
||||
}
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(code).then(function () { done(true); }).catch(function () { done(false); });
|
||||
} else {
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = code;
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { document.execCommand('copy'); done(true); } catch (e) { done(false); }
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user