feat: sync upstream keys and reorder priorities
This commit is contained in:
@@ -18,6 +18,15 @@ from app.services import webhook_service
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
PRIORITY_BASE = 1
|
||||
PRIORITY_STEP = 10
|
||||
|
||||
|
||||
def priority_for_rate_rank(rank: int) -> int:
|
||||
"""Convert a zero-based sorted rate rank to an account priority."""
|
||||
return PRIORITY_BASE + rank * PRIORITY_STEP
|
||||
|
||||
|
||||
def binding_sources(binding: WebsiteGroupBinding) -> list[dict[str, Any]]:
|
||||
try:
|
||||
data = json.loads(binding.source_groups_json or "[]")
|
||||
@@ -187,7 +196,7 @@ def build_rate_priority_map(db: Session, upstream_ids: set[int]) -> dict[str, in
|
||||
|
||||
使用 (upstream_id, group_id) 复合键避免不同上游的同名分组互相覆盖。
|
||||
遍历所有涉及的上游的最新快照,收集分组的倍率,按倍率升序排列后赋值 priority。
|
||||
倍率最低的 priority=1,次低的 priority=2,以此类推。相同倍率的分组共享同一 priority。
|
||||
倍率最低的 priority=1,次低的 priority=11,以此类推。相同倍率的分组共享同一 priority。
|
||||
"""
|
||||
group_rates: dict[str, float] = {}
|
||||
for uid in upstream_ids:
|
||||
@@ -199,7 +208,7 @@ def build_rate_priority_map(db: Session, upstream_ids: set[int]) -> dict[str, in
|
||||
key = f"{uid}:{gid}"
|
||||
group_rates[key] = rate
|
||||
unique_rates = sorted(set(group_rates.values()))
|
||||
rate_to_priority = {rate: idx + 1 for idx, rate in enumerate(unique_rates)}
|
||||
rate_to_priority = {rate: priority_for_rate_rank(idx) for idx, rate in enumerate(unique_rates)}
|
||||
return {key: rate_to_priority[rate] for key, rate in group_rates.items()}
|
||||
|
||||
|
||||
@@ -285,27 +294,30 @@ def _try_send_priority_webhook(
|
||||
logger.warning("account_priority_changed webhook failed for website %s: %s", wid, exc)
|
||||
|
||||
|
||||
def sync_account_priorities_for_upstream(db: Session, upstream_id: int) -> list[dict]:
|
||||
def sync_account_priorities_for_upstream(
|
||||
db: Session,
|
||||
upstream_id: int,
|
||||
website_id: int | None = None,
|
||||
) -> list[dict]:
|
||||
"""上游倍率变化后,自动更新已导入下游账号的 priority。
|
||||
|
||||
只处理同一目标分组内有多个账号(存在竞争)的情况:
|
||||
- 竞争分组键:imported_target_group_id(老数据 fallback 到 group_id)
|
||||
- 同一竞争分组内按倍率升序排序,priority 从 1 开始(相同倍率共享)
|
||||
- 同一竞争分组内按倍率升序排序,priority 从 1 开始,每档间隔 10(相同倍率共享)
|
||||
- 单账号分组:完全跳过,不调用 update_account,不发通知
|
||||
- 无竞争分组:直接返回,不写日志,不发通知
|
||||
"""
|
||||
from collections import defaultdict
|
||||
|
||||
key_rows = (
|
||||
db.query(UpstreamGeneratedKey)
|
||||
.filter(
|
||||
UpstreamGeneratedKey.upstream_id == upstream_id,
|
||||
UpstreamGeneratedKey.imported_website_id.isnot(None),
|
||||
UpstreamGeneratedKey.imported_account_id.isnot(None),
|
||||
UpstreamGeneratedKey.status != "orphaned",
|
||||
)
|
||||
.all()
|
||||
key_query = db.query(UpstreamGeneratedKey).filter(
|
||||
UpstreamGeneratedKey.upstream_id == upstream_id,
|
||||
UpstreamGeneratedKey.imported_website_id.isnot(None),
|
||||
UpstreamGeneratedKey.imported_account_id.isnot(None),
|
||||
UpstreamGeneratedKey.status != "orphaned",
|
||||
)
|
||||
if website_id is not None:
|
||||
key_query = key_query.filter(UpstreamGeneratedKey.imported_website_id == website_id)
|
||||
key_rows = key_query.all()
|
||||
if not key_rows:
|
||||
return []
|
||||
|
||||
@@ -387,7 +399,7 @@ def sync_account_priorities_for_upstream(db: Session, upstream_id: int) -> list[
|
||||
continue
|
||||
# 组内按倍率升序排序(倍率低 → priority 小 → 优先)
|
||||
unique_rates = sorted(set(r for _, r in rated))
|
||||
rate_to_prio = {rate: idx + 1 for idx, rate in enumerate(unique_rates)}
|
||||
rate_to_prio = {rate: priority_for_rate_rank(idx) for idx, rate in enumerate(unique_rates)}
|
||||
for row, rate in rated:
|
||||
priority_assignment[row.imported_account_id] = rate_to_prio[rate]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user