From 2da005ecca87c2acb988ffd31fc892570d76bdab Mon Sep 17 00:00:00 2001 From: hz4th_coder Date: Tue, 18 Aug 2026 00:13:29 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.12=20=E6=96=B0=E9=97=BB=E9=A1=B5=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=EF=BC=9A=E7=B1=BB=E5=88=AB=E7=AD=9B=E9=80=89=E6=A0=87?= =?UTF-8?q?=E7=AD=BE(=E5=85=A8=E9=83=A8/=E6=96=B0=E9=97=BB/=E7=99=BE?= =?UTF-8?q?=E7=A7=91/=E6=80=BB=E5=86=B3=E8=B5=9B/=E7=BB=AD=E7=BA=A6/?= =?UTF-8?q?=E4=B8=AD=E5=9B=BD=E7=90=83=E5=91=98/=E9=80=89=E7=A7=80)=20+=20?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=8E=A7=E4=BB=B6(10=E6=9D=A1/=E9=A1=B5)?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E4=B8=8E=E6=90=9C=E7=B4=A2=E7=BB=84=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.py | 13 ++++--------- static/app.js | 27 ++++++++++++++++++++++----- static/index.html | 12 +++++++++++- tools.py | 22 ++++++++++++++++++++++ 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/api.py b/api.py index 5df96fd..10480c3 100644 --- a/api.py +++ b/api.py @@ -191,15 +191,10 @@ def api_playoffs(): def api_news(): q = request.args.get("q", "") kind = request.args.get("kind", "") - limit = int(request.args.get("limit", 20)) - if q: - r = tools.search_news(q, limit=limit) - return jsonify(r.get("results", [])) - from db import query - rows = query("""SELECT id,title,author,source,publish_time,tags,kind,substr(content,1,160) AS summary - FROM news WHERE (?='' OR kind=?) ORDER BY publish_time DESC, id DESC LIMIT ?""", - (kind, kind, limit)) - return jsonify(rows) + tag = request.args.get("tag", "") + page = max(1, int(request.args.get("page", 1))) + size = min(30, max(1, int(request.args.get("size", 10)))) + return jsonify(tools.list_news(q, kind=kind, tag=tag, page=page, size=size)) @app.route("/api/news/") diff --git a/static/app.js b/static/app.js index ab10f35..b81677a 100644 --- a/static/app.js +++ b/static/app.js @@ -92,7 +92,12 @@ function loadView(v) { $$("#view-games .btn.small").forEach((x) => x.classList.toggle("active", x.dataset.status === "")); loadGames(); } - else if (v === "news") loadNews(""); + else if (v === "news") { + newsPage = 1; newsQ = ""; newsKind = ""; newsTag = ""; + $("#search-news").value = ""; + $$("#view-news .btn.small").forEach((x) => x.classList.toggle("active", !x.dataset.kind && !x.dataset.tag)); + loadNews(); + } else if (v === "persons") loadPersons(""); else if (v === "standings") { if ($("#season-select").options.length) { loadStandings(); loadPlayoffs(); } @@ -411,6 +416,7 @@ function renderPager(d, key) { function goPage(key, p) { if (key === "players") { playersPage = p; loadPlayers(); } else if (key === "games") { gamesPage = p; loadGames(); } + else if (key === "news") { newsPage = p; loadNews(); } } $("#btn-players").addEventListener("click", () => { playersQ = $("#search-players").value.trim(); playersPage = 1; loadPlayers(); }); @@ -497,8 +503,10 @@ async function openGame(id) { } /* ================= 新闻 ================= */ -async function loadNews(q) { - const news = await getJSON(`/api/news?q=${encodeURIComponent(q)}&limit=30`); +let newsPage = 1, newsQ = "", newsKind = "", newsTag = ""; +async function loadNews() { + const d = await getJSON(`/api/news?q=${encodeURIComponent(newsQ)}&kind=${newsKind}&tag=${encodeURIComponent(newsTag)}&page=${newsPage}&size=10`); + const news = d.results || []; $("#list-news").innerHTML = news.map((n) => `
@@ -507,10 +515,19 @@ async function loadNews(q) {
🕐 ${esc(n.publish_time)} · ${esc(n.source)}${n.author ? " · " + esc(n.author) : ""}
${esc(n.summary || n.content || "")}…
-
`).join(""); + `).join("") || '
没有符合条件的新闻
'; + renderPager(d, "news"); } -$("#btn-news").addEventListener("click", () => loadNews($("#search-news").value.trim())); +$("#btn-news").addEventListener("click", () => { newsQ = $("#search-news").value.trim(); newsPage = 1; loadNews(); }); $("#search-news").addEventListener("keydown", (e) => { if (e.key === "Enter") $("#btn-news").click(); }); +$$("#view-news .btn.small").forEach((b) => b.addEventListener("click", () => { + $$("#view-news .btn.small").forEach((x) => x.classList.remove("active")); + b.classList.add("active"); + newsKind = b.dataset.kind; + newsTag = b.dataset.tag; + newsPage = 1; + loadNews(); +})); async function openNews(id) { const n = await getJSON(`/api/news/${id}`); openModal(` diff --git a/static/index.html b/static/index.html index 4173756..d0cc86e 100644 --- a/static/index.html +++ b/static/index.html @@ -82,8 +82,18 @@
-
+
+ + + + + + + + +
+
diff --git a/tools.py b/tools.py index 39186c3..b275dc9 100644 --- a/tools.py +++ b/tools.py @@ -351,6 +351,28 @@ def player_game_logs(player_id, limit=10): return out +# ================================================================== 新闻列表(前台分页版) +def list_news(q="", kind="", tag="", page=1, size=10): + """前台新闻列表:关键词 + 类型(kind) + 话题标签(tag) + 分页""" + conds, args = [], [] + if q: + like = f"%{fuzzy(q)}%" + conds.append("(title LIKE ? ESCAPE '\\' OR content LIKE ? ESCAPE '\\' OR tags LIKE ? ESCAPE '\\')") + args += [like, like, like] + if kind: + conds.append("kind=?") + args.append(kind) + if tag: + conds.append("tags LIKE ? ESCAPE '\\'") + args.append(f"%{fuzzy(tag)}%") + where = ("WHERE " + " AND ".join(conds)) if conds else "" + total = query_one(f"SELECT COUNT(*) AS c FROM news {where}", args)["c"] + rows = query(f"""SELECT id,title,author,source,publish_time,tags,kind,substr(content,1,160) AS summary + FROM news {where} ORDER BY publish_time DESC, id DESC LIMIT ? OFFSET ?""", + args + [size, (page - 1) * size]) + return {"results": rows, "total": total, "page": page, "size": size} + + # ================================================================== 新闻(SQL 关键词 + 向量语义 + 可选 rerank 融合) def search_news(query_text, limit=5): q = (query_text or "").strip()