Add month/quarter/half-year/all list window presets with this month as default.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -236,9 +236,14 @@ from lib.common.wechat_notify_lib import build_wechat_rs_level_message, send_wec
|
||||
from lib.hub.hub_auth import request_allowed as hub_request_allowed
|
||||
from lib.hub.hub_volume_rank_lib import resolve_daily_volume_rank
|
||||
from lib.common.history_window_lib import (
|
||||
PRESET_ALL,
|
||||
PRESET_CUSTOM,
|
||||
PRESET_DEFAULT,
|
||||
PRESET_UTC_LAST24H,
|
||||
PRESET_UTC_LAST3M,
|
||||
PRESET_UTC_LAST6M,
|
||||
PRESET_UTC_LAST7D,
|
||||
PRESET_UTC_THIS_MONTH,
|
||||
PRESET_UTC_TODAY,
|
||||
list_window_redirect_query,
|
||||
normalize_bj_datetime_storage,
|
||||
@@ -1672,7 +1677,7 @@ def _count_opens_between(conn, start_td, end_td):
|
||||
|
||||
|
||||
def _list_window_from_request():
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_UTC_TODAY)
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_DEFAULT)
|
||||
|
||||
|
||||
def _redirect_records():
|
||||
@@ -7284,6 +7289,10 @@ def render_main_page(page="trade", embed_mode=None):
|
||||
data_export_version=3,
|
||||
list_window=list_window,
|
||||
list_window_presets={
|
||||
"utc_this_month": PRESET_UTC_THIS_MONTH,
|
||||
"utc_last3m": PRESET_UTC_LAST3M,
|
||||
"utc_last6m": PRESET_UTC_LAST6M,
|
||||
"all": PRESET_ALL,
|
||||
"utc_today": PRESET_UTC_TODAY,
|
||||
"utc_last24h": PRESET_UTC_LAST24H,
|
||||
"utc_last7d": PRESET_UTC_LAST7D,
|
||||
|
||||
@@ -238,9 +238,14 @@ from lib.hub.hub_auth import request_allowed as hub_request_allowed
|
||||
from lib.instance.instance_nav_lib import request_is_hub_soft_nav
|
||||
from lib.hub.hub_volume_rank_lib import resolve_daily_volume_rank
|
||||
from lib.common.history_window_lib import (
|
||||
PRESET_ALL,
|
||||
PRESET_CUSTOM,
|
||||
PRESET_DEFAULT,
|
||||
PRESET_UTC_LAST24H,
|
||||
PRESET_UTC_LAST3M,
|
||||
PRESET_UTC_LAST6M,
|
||||
PRESET_UTC_LAST7D,
|
||||
PRESET_UTC_THIS_MONTH,
|
||||
PRESET_UTC_TODAY,
|
||||
list_window_redirect_query,
|
||||
normalize_bj_datetime_storage,
|
||||
@@ -1669,7 +1674,7 @@ def _count_opens_between(conn, start_td, end_td):
|
||||
|
||||
|
||||
def _list_window_from_request():
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_UTC_TODAY)
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_DEFAULT)
|
||||
|
||||
|
||||
def _redirect_records():
|
||||
@@ -7078,6 +7083,10 @@ def render_main_page(page="trade", embed_mode=None):
|
||||
data_export_version=3,
|
||||
list_window=list_window,
|
||||
list_window_presets={
|
||||
"utc_this_month": PRESET_UTC_THIS_MONTH,
|
||||
"utc_last3m": PRESET_UTC_LAST3M,
|
||||
"utc_last6m": PRESET_UTC_LAST6M,
|
||||
"all": PRESET_ALL,
|
||||
"utc_today": PRESET_UTC_TODAY,
|
||||
"utc_last24h": PRESET_UTC_LAST24H,
|
||||
"utc_last7d": PRESET_UTC_LAST7D,
|
||||
|
||||
@@ -235,9 +235,14 @@ from lib.hub.hub_auth import request_allowed as hub_request_allowed
|
||||
from lib.instance.instance_nav_lib import request_is_hub_soft_nav
|
||||
from lib.hub.hub_volume_rank_lib import resolve_daily_volume_rank
|
||||
from lib.common.history_window_lib import (
|
||||
PRESET_ALL,
|
||||
PRESET_CUSTOM,
|
||||
PRESET_DEFAULT,
|
||||
PRESET_UTC_LAST24H,
|
||||
PRESET_UTC_LAST3M,
|
||||
PRESET_UTC_LAST6M,
|
||||
PRESET_UTC_LAST7D,
|
||||
PRESET_UTC_THIS_MONTH,
|
||||
PRESET_UTC_TODAY,
|
||||
list_window_redirect_query,
|
||||
normalize_bj_datetime_storage,
|
||||
@@ -1674,7 +1679,7 @@ def _count_opens_between(conn, start_td, end_td):
|
||||
|
||||
|
||||
def _list_window_from_request():
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_UTC_TODAY)
|
||||
return resolve_list_window(request.args, session, default_preset=PRESET_DEFAULT)
|
||||
|
||||
|
||||
def _redirect_records():
|
||||
@@ -6686,6 +6691,10 @@ def render_main_page(page="trade", embed_mode=None):
|
||||
data_export_version=3,
|
||||
list_window=list_window,
|
||||
list_window_presets={
|
||||
"utc_this_month": PRESET_UTC_THIS_MONTH,
|
||||
"utc_last3m": PRESET_UTC_LAST3M,
|
||||
"utc_last6m": PRESET_UTC_LAST6M,
|
||||
"all": PRESET_ALL,
|
||||
"utc_today": PRESET_UTC_TODAY,
|
||||
"utc_last24h": PRESET_UTC_LAST24H,
|
||||
"utc_last7d": PRESET_UTC_LAST7D,
|
||||
|
||||
@@ -5,7 +5,12 @@ from datetime import datetime, timedelta, timezone
|
||||
PRESET_UTC_TODAY = "utc_today"
|
||||
PRESET_UTC_LAST24H = "utc_last24h"
|
||||
PRESET_UTC_LAST7D = "utc_last7d"
|
||||
PRESET_UTC_THIS_MONTH = "utc_this_month"
|
||||
PRESET_UTC_LAST3M = "utc_last3m"
|
||||
PRESET_UTC_LAST6M = "utc_last6m"
|
||||
PRESET_ALL = "all"
|
||||
PRESET_CUSTOM = "custom"
|
||||
PRESET_DEFAULT = PRESET_UTC_THIS_MONTH
|
||||
|
||||
|
||||
def utc_now():
|
||||
@@ -18,12 +23,12 @@ def utc_today_bounds(now=None):
|
||||
return start, now
|
||||
|
||||
|
||||
def resolve_window(query_mapping, default_preset=PRESET_UTC_TODAY):
|
||||
def resolve_window(query_mapping, default_preset=PRESET_DEFAULT):
|
||||
"""
|
||||
从 ?win_preset= & from_utc= & to_utc= 解析窗口。
|
||||
返回 dict: preset, start_utc, end_utc, label, start_ms, end_ms
|
||||
"""
|
||||
preset = (query_mapping.get("win_preset") or default_preset or PRESET_UTC_TODAY).strip().lower()
|
||||
preset = (query_mapping.get("win_preset") or default_preset or PRESET_DEFAULT).strip().lower()
|
||||
now = utc_now()
|
||||
|
||||
if preset == PRESET_UTC_LAST24H:
|
||||
@@ -34,16 +39,36 @@ def resolve_window(query_mapping, default_preset=PRESET_UTC_TODAY):
|
||||
start = now - timedelta(days=7)
|
||||
end = now
|
||||
label = "近7天(UTC)"
|
||||
elif preset == PRESET_UTC_THIS_MONTH:
|
||||
start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
||||
end = now
|
||||
label = f"本月 {start.strftime('%Y-%m')}"
|
||||
elif preset == PRESET_UTC_LAST3M:
|
||||
start = now - timedelta(days=90)
|
||||
end = now
|
||||
label = "近3月"
|
||||
elif preset == PRESET_UTC_LAST6M:
|
||||
start = now - timedelta(days=180)
|
||||
end = now
|
||||
label = "近6月"
|
||||
elif preset == PRESET_ALL:
|
||||
start = datetime(2000, 1, 1, tzinfo=timezone.utc)
|
||||
end = now
|
||||
label = "全部"
|
||||
elif preset == PRESET_CUSTOM:
|
||||
start = _parse_utc_input(query_mapping.get("from_utc")) or utc_today_bounds(now)[0]
|
||||
end = _parse_utc_input(query_mapping.get("to_utc")) or now
|
||||
if end < start:
|
||||
start, end = end, start
|
||||
label = f"{start.strftime('%Y-%m-%d %H:%M')} ~ {end.strftime('%Y-%m-%d %H:%M')} UTC"
|
||||
else:
|
||||
elif preset == PRESET_UTC_TODAY:
|
||||
start, end = utc_today_bounds(now)
|
||||
preset = PRESET_UTC_TODAY
|
||||
label = f"UTC当日 {start.strftime('%Y-%m-%d')}"
|
||||
else:
|
||||
return resolve_window(
|
||||
{**(query_mapping or {}), "win_preset": default_preset},
|
||||
default_preset=default_preset,
|
||||
)
|
||||
|
||||
return {
|
||||
"preset": preset,
|
||||
@@ -130,7 +155,7 @@ def query_mapping_from_session(session_store):
|
||||
}
|
||||
|
||||
|
||||
def resolve_list_window(query_mapping, session_store=None, default_preset=PRESET_UTC_TODAY):
|
||||
def resolve_list_window(query_mapping, session_store=None, default_preset=PRESET_DEFAULT):
|
||||
"""
|
||||
URL 带 win_preset 时解析并写入 session;无参数时用 session 中上次「应用」的预设。
|
||||
"""
|
||||
|
||||
@@ -230,7 +230,7 @@ function deleteKeyHistory(id){
|
||||
|
||||
function listWindowQueryString(){
|
||||
const presetEl = document.getElementById("win-preset-select");
|
||||
const preset = (presetEl && presetEl.value) || new URLSearchParams(window.location.search).get("win_preset") || "utc_today";
|
||||
const preset = (presetEl && presetEl.value) || new URLSearchParams(window.location.search).get("win_preset") || "utc_this_month";
|
||||
const q = new URLSearchParams(window.location.search);
|
||||
q.set("win_preset", preset);
|
||||
if(preset === "custom"){
|
||||
|
||||
@@ -759,7 +759,7 @@ function deleteKeyHistory(id){
|
||||
|
||||
function listWindowQueryString(){
|
||||
const presetEl = document.getElementById("win-preset-select");
|
||||
const preset = (presetEl && presetEl.value) || new URLSearchParams(window.location.search).get("win_preset") || "utc_today";
|
||||
const preset = (presetEl && presetEl.value) || new URLSearchParams(window.location.search).get("win_preset") || "utc_this_month";
|
||||
const q = new URLSearchParams(window.location.search);
|
||||
q.set("win_preset", preset);
|
||||
if(preset === "custom"){
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
<div class="instance-header-panel card">
|
||||
<div class="instance-header-toolbar">
|
||||
<div class="instance-header-toolbar-filter">
|
||||
<span class="list-window-label" title="列表按 UTC 时间筛选,默认当日">UTC {{ list_window.label }}</span>
|
||||
<span class="list-window-label" title="列表按 UTC 时间筛选,默认本月">UTC {{ list_window.label }}</span>
|
||||
<label class="list-window-preset">预设
|
||||
<select id="win-preset-select" onchange="toggleListWindowCustom()">
|
||||
<option value="utc_this_month" {% if list_window.preset == 'utc_this_month' %}selected{% endif %}>本月</option>
|
||||
<option value="utc_last3m" {% if list_window.preset == 'utc_last3m' %}selected{% endif %}>近3月</option>
|
||||
<option value="utc_last6m" {% if list_window.preset == 'utc_last6m' %}selected{% endif %}>近6月</option>
|
||||
<option value="all" {% if list_window.preset == 'all' %}selected{% endif %}>全部</option>
|
||||
<option value="utc_today" {% if list_window.preset == 'utc_today' %}selected{% endif %}>UTC 当日</option>
|
||||
<option value="utc_last24h" {% if list_window.preset == 'utc_last24h' %}selected{% endif %}>近 24 小时</option>
|
||||
<option value="utc_last7d" {% if list_window.preset == 'utc_last7d' %}selected{% endif %}>近 7 天</option>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
"""history_window_lib 单元测试。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from datetime import datetime, timezone
|
||||
from unittest.mock import patch
|
||||
|
||||
from lib.common.history_window_lib import (
|
||||
PRESET_ALL,
|
||||
PRESET_DEFAULT,
|
||||
PRESET_UTC_LAST3M,
|
||||
PRESET_UTC_THIS_MONTH,
|
||||
resolve_window,
|
||||
)
|
||||
|
||||
|
||||
class TestHistoryWindowLib(unittest.TestCase):
|
||||
def test_default_is_this_month(self):
|
||||
self.assertEqual(PRESET_DEFAULT, PRESET_UTC_THIS_MONTH)
|
||||
|
||||
def test_resolve_this_month(self):
|
||||
now = datetime(2026, 7, 8, 12, 0, 0, tzinfo=timezone.utc)
|
||||
with patch("lib.common.history_window_lib.utc_now", return_value=now):
|
||||
win = resolve_window({"win_preset": PRESET_UTC_THIS_MONTH})
|
||||
self.assertEqual(win["preset"], PRESET_UTC_THIS_MONTH)
|
||||
self.assertIn("本月", win["label"])
|
||||
self.assertEqual(win["start_utc"].month, 7)
|
||||
self.assertEqual(win["start_utc"].day, 1)
|
||||
|
||||
def test_resolve_last3m_and_all(self):
|
||||
now = datetime(2026, 7, 8, 12, 0, 0, tzinfo=timezone.utc)
|
||||
with patch("lib.common.history_window_lib.utc_now", return_value=now):
|
||||
w3 = resolve_window({"win_preset": PRESET_UTC_LAST3M})
|
||||
wall = resolve_window({"win_preset": PRESET_ALL})
|
||||
self.assertEqual(w3["label"], "近3月")
|
||||
self.assertEqual(wall["label"], "全部")
|
||||
self.assertLess(wall["start_utc"].year, 2020)
|
||||
|
||||
def test_empty_preset_uses_default_month(self):
|
||||
now = datetime(2026, 7, 8, 12, 0, 0, tzinfo=timezone.utc)
|
||||
with patch("lib.common.history_window_lib.utc_now", return_value=now):
|
||||
win = resolve_window({})
|
||||
self.assertEqual(win["preset"], PRESET_UTC_THIS_MONTH)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user