fix: 删除 routers/websites 中残留的死代码函数 _build_rate_priority_map,并为 build_target_group_priority_map 引入严格的分组倍率解析,防止非法/缺失倍率的分组以 1.0 的降级值参与排序
This commit is contained in:
@@ -189,12 +189,6 @@ def _numeric_group_id(value: str | None) -> int | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _build_rate_priority_map(db: Session, upstream_ids: set[int]) -> dict[str, int]:
|
|
||||||
"""根据上游分组倍率构建 group_id → priority 映射。
|
|
||||||
|
|
||||||
委托给 website_sync.build_rate_priority_map 避免逻辑重复。
|
|
||||||
"""
|
|
||||||
return build_rate_priority_map(db, upstream_ids)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/websites", response_model=List[WebsiteResponse])
|
@router.get("/api/websites", response_model=List[WebsiteResponse])
|
||||||
|
|||||||
@@ -220,6 +220,17 @@ def _snapshot_group_rate(group: dict) -> float:
|
|||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
|
|
||||||
|
def _strict_snapshot_group_rate(group: dict) -> float | None:
|
||||||
|
"""从快照分组数据中严格提取倍率,若缺失或非数值则返回 None。"""
|
||||||
|
raw = group.get("rate") or group.get("default_rate") or group.get("rate_multiplier")
|
||||||
|
if raw is None or raw == "":
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return float(raw)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def build_rate_priority_map(db: Session, upstream_ids: set[int]) -> dict[str, int]:
|
def build_rate_priority_map(db: Session, upstream_ids: set[int]) -> dict[str, int]:
|
||||||
"""根据上游分组倍率构建 f"{upstream_id}:{group_id}" → priority 映射。
|
"""根据上游分组倍率构建 f"{upstream_id}:{group_id}" → priority 映射。
|
||||||
|
|
||||||
@@ -465,8 +476,9 @@ def build_target_group_priority_map(
|
|||||||
groups = rate_maps.get(upstream_id) or {}
|
groups = rate_maps.get(upstream_id) or {}
|
||||||
g = groups.get(group_id)
|
g = groups.get(group_id)
|
||||||
if isinstance(g, dict):
|
if isinstance(g, dict):
|
||||||
rate = _snapshot_group_rate(g)
|
rate = _strict_snapshot_group_rate(g)
|
||||||
rated_sources.append(((upstream_id, group_id), rate))
|
if rate is not None:
|
||||||
|
rated_sources.append(((upstream_id, group_id), rate))
|
||||||
|
|
||||||
if not rated_sources:
|
if not rated_sources:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ def test_target_group_priority_calculation(db_session):
|
|||||||
"G3": 0.07,
|
"G3": 0.07,
|
||||||
"G4": 0.08,
|
"G4": 0.08,
|
||||||
"G5": 0.05, # identical rate as G1
|
"G5": 0.05, # identical rate as G1
|
||||||
|
"G6": "invalid_rate", # invalid rate
|
||||||
})
|
})
|
||||||
|
|
||||||
target_group_sources = {
|
target_group_sources = {
|
||||||
@@ -71,6 +72,8 @@ def test_target_group_priority_calculation(db_session):
|
|||||||
(u1.id, "G3"),
|
(u1.id, "G3"),
|
||||||
(u1.id, "G4"),
|
(u1.id, "G4"),
|
||||||
(u1.id, "G5"),
|
(u1.id, "G5"),
|
||||||
|
(u1.id, "G6"),
|
||||||
|
(u1.id, "G7"), # non-existent G7
|
||||||
],
|
],
|
||||||
"TG2": [
|
"TG2": [
|
||||||
(u1.id, "G2"), # rates 0.065 -> priority 1
|
(u1.id, "G2"), # rates 0.065 -> priority 1
|
||||||
@@ -90,6 +93,8 @@ def test_target_group_priority_calculation(db_session):
|
|||||||
assert priority_map[("TG1", u1.id, "G2")] == 11
|
assert priority_map[("TG1", u1.id, "G2")] == 11
|
||||||
assert priority_map[("TG1", u1.id, "G3")] == 21
|
assert priority_map[("TG1", u1.id, "G3")] == 21
|
||||||
assert priority_map[("TG1", u1.id, "G4")] == 31
|
assert priority_map[("TG1", u1.id, "G4")] == 31
|
||||||
|
assert ("TG1", u1.id, "G6") not in priority_map
|
||||||
|
assert ("TG1", u1.id, "G7") not in priority_map
|
||||||
|
|
||||||
# Assert priority values in TG2 (starts from 1 independently)
|
# Assert priority values in TG2 (starts from 1 independently)
|
||||||
# 0.065 -> rank 0 -> priority 1
|
# 0.065 -> rank 0 -> priority 1
|
||||||
|
|||||||
Reference in New Issue
Block a user