feat: stabilize multi-region runtime sync and worker orchestration

This commit is contained in:
root
2026-04-27 15:48:12 +08:00
parent 7cbde2aa78
commit 215a364891
137 changed files with 31931 additions and 1943 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
from datetime import datetime
from math import ceil
from app.core.db import get_db
@@ -113,6 +114,8 @@ def _build_step_details(row: tuple) -> list[dict]:
_normalize_step_detail("时光机", row[21]),
_normalize_step_detail("站长之家", row[22]),
_normalize_step_detail("爱站网", row[23]),
_normalize_step_detail("桔子SEO", row[24]),
_normalize_step_detail("聚查", row[25]),
]
@@ -152,6 +155,28 @@ def _normalize_detection_update(value) -> bool | None:
raise ValueError("检测结果字段仅支持“是”或“否”")
def _now_text() -> str:
return datetime.now().isoformat(sep=" ", timespec="seconds")
def _merge_detection_step_update(field: str, value: bool, existing_payload) -> dict | bool:
if field == "is_chinese_title":
return bool(value)
existing = dict(existing_payload or {}) if isinstance(existing_payload, dict) else {}
previous_status = existing.get("status") if isinstance(existing.get("status"), bool) else None
merged = dict(existing)
merged["status"] = bool(value)
merged["state"] = "passed" if bool(value) else "failed"
merged["step"] = str(merged.get("step") or field)
if previous_status != bool(value) or not str(merged.get("message") or "").strip():
merged["message"] = "人工批量更新"
if previous_status != bool(value) or not str(merged.get("checked_at") or "").strip():
merged["checked_at"] = _now_text()
merged["manual_override"] = True
return merged
def _build_domain_query_parts(filters: dict | None = None) -> tuple[str, str, list[object]]:
filters = filters or {}
conditions: list[str] = []
@@ -190,8 +215,9 @@ def _build_domain_query_parts(filters: dict | None = None) -> tuple[str, str, li
if filters.get("source_type") is not None:
conditions.append("d.source_type = %s")
params.append(int(filters["source_type"]))
if filters.get("backlink_gt_10"):
conditions.append("coalesce(dd.backlink_count_gt_10, false) = true")
if filters.get("backlink_gt_10") is not None:
conditions.append("coalesce(dd.backlink_count_gt_10, false) = %s")
params.append(bool(filters["backlink_gt_10"]))
from_clause = """
from domains d
@@ -264,7 +290,9 @@ def fetch_domains(
dd.google_site,
dd.wayback_info,
dd.chinaz_info,
dd.aizhan_info
dd.aizhan_info,
dd.juziseo_info,
dd.jucha_info
{from_clause}
{where_clause}
order by d.id desc
@@ -360,26 +388,7 @@ def fetch_domain_detail(domain_id: int) -> dict | None:
if not row:
return None
step_details = [
_normalize_step_detail("百度历史收录", row[16]),
_normalize_step_detail("百度Site收录", row[17]),
{
"label": "标题为中文",
"state": "passed" if bool(row[18]) else "",
"status": bool(row[18]),
"message": "标题含中文" if bool(row[18]) else "",
"checked_at": "",
"step": "中文标题",
"raw": row[18],
},
_normalize_step_detail("360 Site收录", row[19]),
_normalize_step_detail("Google Site收录", row[20]),
_normalize_step_detail("时光机", row[21]),
_normalize_step_detail("站长之家", row[22]),
_normalize_step_detail("爱站网", row[23]),
_normalize_step_detail("桔子SEO", row[24]),
_normalize_step_detail("聚查", row[25]),
]
step_details = _build_step_details(row)
step_summary = _summarize_step_details(step_details)
return {
"id": row[0],
@@ -523,6 +532,34 @@ def batch_update_domains(domain_ids: list[int], updates: dict) -> dict:
tuple(params),
)
existing_detection_payloads: dict[str, object] = {}
existing_detection_row = None
if "backlink_count" in payload or detection_fields.intersection(payload.keys()):
cur.execute(
"""
select
id,
baidu_history,
baidu_site,
is_chinese_title,
qihu360_site,
google_site,
backlink_count_gt_10
from domain_detections
where domain_id = %s
""",
(domain_id,),
)
existing_detection_row = cur.fetchone()
if existing_detection_row:
existing_detection_payloads = {
"baidu_history": existing_detection_row[1],
"baidu_site": existing_detection_row[2],
"is_chinese_title": existing_detection_row[3],
"qihu360_site": existing_detection_row[4],
"google_site": existing_detection_row[5],
}
detection_payload: dict[str, object] = {}
for field in detection_fields:
if field not in payload:
@@ -530,15 +567,15 @@ def batch_update_domains(domain_ids: list[int], updates: dict) -> dict:
normalized = _normalize_detection_update(payload[field])
if normalized is None:
continue
if field == "is_chinese_title":
detection_payload[field] = normalized
else:
detection_payload[field] = {"status": normalized}
detection_payload[field] = _merge_detection_step_update(
field,
normalized,
existing_detection_payloads.get(field),
)
if "backlink_count" in payload:
backlink_gt_10 = int(payload["backlink_count"]) > 10
cur.execute("select id from domain_detections where domain_id = %s", (domain_id,))
if cur.fetchone():
if existing_detection_row:
cur.execute(
"update domain_detections set backlink_count_gt_10 = %s, update_time = now() where domain_id = %s",
(backlink_gt_10, domain_id),
@@ -553,9 +590,7 @@ def batch_update_domains(domain_ids: list[int], updates: dict) -> dict:
)
if detection_payload:
cur.execute("select id from domain_detections where domain_id = %s", (domain_id,))
existing_detection = cur.fetchone()
if existing_detection:
if existing_detection_row:
detection_set_parts: list[str] = []
detection_params: list[object] = []
for field, value in detection_payload.items():