v2.6.0 历史分页+筛选+搜索+表头升降排序;一键清空历史(DELETE /api/tests);右下角置顶/置底悬浮按钮
This commit is contained in:
+70
-3
@@ -2,6 +2,7 @@
|
||||
"""SQLite 存储:提供商配置 / 测试记录 / 每次采样指标 / 全量日志"""
|
||||
import os
|
||||
import json
|
||||
import math
|
||||
import sqlite3
|
||||
import threading
|
||||
import time
|
||||
@@ -204,20 +205,86 @@ def get_test(tid: int):
|
||||
conn.close()
|
||||
|
||||
|
||||
def list_tests(limit=100):
|
||||
# 历史列表排序字段 → 取值函数(数值字段取 summary 聚合值,None 恒排最后)
|
||||
SORT_KEYS = {
|
||||
"id": lambda t: t["id"],
|
||||
"created_at": lambda t: t["created_at"],
|
||||
"name": lambda t: (t.get("name") or "").lower(),
|
||||
"provider": lambda t: (t.get("provider") or "").lower(),
|
||||
"model": lambda t: (t.get("model") or "").lower(),
|
||||
"status": lambda t: t.get("status") or "",
|
||||
"samples": lambda t: (t.get("summary") or {}).get("samples_ok"),
|
||||
"ttft": lambda t: (t.get("summary") or {}).get("avg_ttft_ms"),
|
||||
"prefill": lambda t: (t.get("summary") or {}).get("avg_prefill_speed"),
|
||||
"decode": lambda t: (t.get("summary") or {}).get("avg_decode_speed"),
|
||||
"total_ms": lambda t: (t.get("summary") or {}).get("avg_total_ms"),
|
||||
}
|
||||
|
||||
|
||||
def query_tests(q="", status="", provider="", sort="id", order="desc",
|
||||
page=1, page_size=20):
|
||||
"""历史记录:关键词搜索 + 状态/提供商筛选 + 字段排序 + 分页。
|
||||
返回 {"items": [...], "total": N, "page": p, "page_size": s, "total_pages": n}"""
|
||||
with _lock:
|
||||
conn = _connect()
|
||||
try:
|
||||
where, args = [], []
|
||||
if q:
|
||||
like = "%" + q + "%"
|
||||
where.append("(id LIKE ? OR name LIKE ? OR model LIKE ? OR provider LIKE ?"
|
||||
" OR status LIKE ? OR created_at LIKE ?)")
|
||||
args += [like] * 6
|
||||
if status:
|
||||
sts = [s.strip() for s in status.split(",") if s.strip()]
|
||||
if sts:
|
||||
where.append("status IN (%s)" % ",".join("?" * len(sts)))
|
||||
args += sts
|
||||
if provider:
|
||||
where.append("provider = ?")
|
||||
args.append(provider)
|
||||
wsql = ("WHERE " + " AND ".join(where)) if where else ""
|
||||
|
||||
rows = conn.execute(
|
||||
"SELECT id,created_at,status,provider,model,name,summary_json,gen_cfg_json,error "
|
||||
"FROM tests ORDER BY id DESC LIMIT ?", (limit,)).fetchall()
|
||||
"FROM tests " + wsql + " ORDER BY id DESC", args).fetchall()
|
||||
out = []
|
||||
for r in rows:
|
||||
d = dict(r)
|
||||
d["summary"] = json.loads(d.pop("summary_json") or "{}")
|
||||
d["gen"] = json.loads(d.pop("gen_cfg_json") or "{}")
|
||||
out.append(d)
|
||||
return out
|
||||
|
||||
# Python 侧排序:None 值恒排最后(无论升降序)
|
||||
keyfn = SORT_KEYS.get(sort) or SORT_KEYS["id"]
|
||||
present = [t for t in out if keyfn(t) is not None]
|
||||
absent = [t for t in out if keyfn(t) is None]
|
||||
present.sort(key=keyfn, reverse=(order == "desc"))
|
||||
out = present + absent
|
||||
|
||||
total = len(out)
|
||||
total_pages = max(1, math.ceil(total / page_size))
|
||||
page = min(max(1, page), total_pages)
|
||||
start = (page - 1) * page_size
|
||||
return {
|
||||
"items": out[start:start + page_size],
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
"total_pages": total_pages,
|
||||
}
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def clear_tests():
|
||||
"""一键清空全部历史(测试记录 + 采样指标 + 日志)"""
|
||||
with _lock:
|
||||
conn = _connect()
|
||||
try:
|
||||
conn.execute("DELETE FROM test_runs")
|
||||
conn.execute("DELETE FROM logs")
|
||||
conn.execute("DELETE FROM tests")
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user