feat(web): dropdown sort and time filters with year support

This commit is contained in:
kairee committed 2026-11-01 12:45:40 +08:00
1 parent bc3bef0743
commit 9be7d1cab2
10 files changed
+191 -67

No files matched your search

+54 -14
View File
@@ -286,6 +286,7 @@ class DashboardQueries:
q: str | None = None,
within_field: str | None = None,
within_start: str | None = None,
within_end: str | None = None,
up_mid: int | None = None,
) -> list[dict[str, Any]]:
clauses = [f"v.status IN ({','.join('?' for _ in statuses)})"]
@@ -302,12 +303,17 @@ class DashboardQueries:
"(v.title LIKE ? ESCAPE '\\' OR v.up_name LIKE ? ESCAPE '\\')"
)
params.extend([pattern, pattern])
if within_field and within_start:
if within_field:
if within_field not in {"pubdate", "first_seen"}:
raise ValueError("within_field 必须是 pubdate 或 first_seen")
start_ts, _ = day_bounds(within_start)
clauses.append(f"v.{within_field} >= ?")
params.append(start_ts)
if within_start:
start_ts, _ = day_bounds(within_start)
clauses.append(f"v.{within_field} >= ?")
params.append(start_ts)
if within_end:
end_ts, _ = day_bounds(within_end)
clauses.append(f"v.{within_field} < ?")
params.append(end_ts)
sql = (
"SELECT v.*, f.title AS folder_title, f.year AS folder_year "
"FROM video v LEFT JOIN folder f ON f.media_id = v.folder_id "
@@ -490,6 +496,14 @@ class DashboardQueries:
cfg = self.config_store.get()
fans = self._fans_overview(conn, cfg.track_fans, latest, snapshot_days)
folders = self._folders_overview(conn)
pub_years = sorted(
{
int(shanghai_date(int(video["pubdate"]))[:4])
for video in videos
if int(video.get("pubdate") or 0) > 0
},
reverse=True,
)
tasks = self._task_records(conn)
auth = {
"ok": self._kv(conn, "auth:ok"),
@@ -527,6 +541,7 @@ class DashboardQueries:
"snapshot_completed_today": snapshot_completed_today,
"fans": fans,
"folders": folders,
"years": pub_years,
"tasks": tasks,
"auth": auth,
"preview": preview,
@@ -650,6 +665,7 @@ class DashboardQueries:
*,
sort: str = "heat",
within_days: int | None = None,
year: int | None = None,
growth_days: int = 7,
folder_id: int | None = None,
q: str | None = None,
@@ -659,6 +675,7 @@ class DashboardQueries:
params = {
"sort": sort,
"within_days": within_days,
"year": year,
"growth_days": growth_days,
"folder_id": folder_id,
"q": q or "",
@@ -669,6 +686,7 @@ class DashboardQueries:
"videos", params, TTL_VIDEOS, lambda: self._list_videos_uncached(
sort=sort,
within_days=within_days,
year=year,
growth_days=growth_days,
folder_id=folder_id,
q=q,
@@ -682,6 +700,7 @@ class DashboardQueries:
*,
sort: str = "heat",
within_days: int | None = None,
year: int | None = None,
growth_days: int = 7,
folder_id: int | None = None,
q: str | None = None,
@@ -701,19 +720,24 @@ class DashboardQueries:
duration_sorts = {"efficiency", "interaction_efficiency"}
min_view_for_ranking = max(0, int(analytics.min_view_for_ranking))
within_field = None
if within_days is not None:
within_start: str | None = None
within_end: str | None = None
if year is not None:
within_field = "pubdate"
within_start = f"{int(year)}-01-01"
within_end = f"{int(year) + 1}-01-01"
elif within_days is not None:
if within_days < 1:
raise ValueError("within_days 必须大于 0")
within_field = "first_seen" if sort == "added" else "pubdate"
within_start = _date_minus(latest, int(within_days) - 1)
videos = self._videos(
conn,
folder_id=folder_id,
q=q,
within_field=within_field,
within_start=(
_date_minus(latest, int(within_days) - 1)
if within_days is not None else None
),
within_start=within_start,
within_end=within_end,
)
aids = [int(video["aid"]) for video in videos]
snapshots = self._snapshot_map(conn, aids)
@@ -862,6 +886,7 @@ class DashboardQueries:
return {
"sort": sort,
"within_days": within_days,
"year": year,
"growth_days": growth_days,
"page": page,
"page_size": page_size,
@@ -973,6 +998,7 @@ class DashboardQueries:
*,
sort: str = "avg_views",
within_days: int | None = None,
year: int | None = None,
q: str | None = None,
min_videos: int = 1,
page: int = 1,
@@ -981,6 +1007,7 @@ class DashboardQueries:
params = {
"sort": sort,
"within_days": within_days,
"year": year,
"q": q or "",
"min_videos": min_videos,
"page": page,
@@ -990,6 +1017,7 @@ class DashboardQueries:
"videos", params, TTL_VIDEOS, lambda: self._list_ups_uncached(
sort=sort,
within_days=within_days,
year=year,
q=q,
min_videos=min_videos,
page=page,
@@ -1002,6 +1030,7 @@ class DashboardQueries:
*,
sort: str = "avg_views",
within_days: int | None = None,
year: int | None = None,
q: str | None = None,
min_videos: int = 1,
page: int = 1,
@@ -1015,14 +1044,24 @@ class DashboardQueries:
def run(conn: sqlite3.Connection) -> dict[str, Any]:
latest = self._latest_date(conn) or self._today()
if year is not None:
within_field = "pubdate"
within_start: str | None = f"{int(year)}-01-01"
within_end: str | None = f"{int(year) + 1}-01-01"
elif within_days is not None:
within_field = "pubdate"
within_start = _date_minus(latest, int(within_days) - 1)
within_end = None
else:
within_field = None
within_start = None
within_end = None
videos = self._videos(
conn,
q=q,
within_field="pubdate" if within_days is not None else None,
within_start=(
_date_minus(latest, int(within_days) - 1)
if within_days is not None else None
),
within_field=within_field,
within_start=within_start,
within_end=within_end,
)
snapshots = self._snapshot_map(conn, [int(video["aid"]) for video in videos])
groups: dict[int, dict[str, Any]] = {}
@@ -1147,6 +1186,7 @@ class DashboardQueries:
return {
"sort": sort,
"within_days": within_days,
"year": year,
"min_videos": min_videos,
"page": page,
"page_size": page_size,