diff --git a/frontend/components/account/AccountCenter.tsx b/frontend/components/account/AccountCenter.tsx index 5a94b5e1..85903214 100644 --- a/frontend/components/account/AccountCenter.tsx +++ b/frontend/components/account/AccountCenter.tsx @@ -49,6 +49,8 @@ type AuthMeResponse = { user_id?: string | null; email?: string | null; points?: number; + weekly_points?: number; + weekly_rank?: number | string | null; entitlement_mode?: string | null; auth_required?: boolean; subscription_required?: boolean; @@ -126,7 +128,12 @@ type InfoRowProps = { isPrimary?: boolean; }; -const InfoRow = ({ icon: Icon, label, value, isPrimary = false }: InfoRowProps) => ( +const InfoRow = ({ + icon: Icon, + label, + value, + isPrimary = false, +}: InfoRowProps) => (
- 积分体系 v4.3 · 管理身份与订阅计划 -
- 将下方命令发送给 Bot,实现全平台气象推送与权限同步。 + 将下方命令发送给到群聊,实现全平台气象推送与权限同步。
diff --git a/src/database/db_manager.py b/src/database/db_manager.py
index 9c70a006..dff9cfd1 100644
--- a/src/database/db_manager.py
+++ b/src/database/db_manager.py
@@ -392,3 +392,43 @@ class DBManager:
(week_key, limit),
)
return [dict(row) for row in cursor.fetchall()]
+
+ def get_weekly_profile_by_supabase_user_id(self, supabase_user_id: str) -> Dict[str, Any]:
+ key = str(supabase_user_id or "").strip().lower()
+ if not key:
+ return {"weekly_points": 0, "weekly_rank": None, "total_ranked": 0}
+
+ now = datetime.now()
+ iso_year, iso_week, _ = now.isocalendar()
+ week_key = f"{iso_year}-W{iso_week:02d}"
+ with self._get_connection() as conn:
+ conn.row_factory = sqlite3.Row
+ rows = conn.execute(
+ """
+ SELECT
+ telegram_id,
+ lower(trim(COALESCE(supabase_user_id, ''))) AS supabase_key,
+ COALESCE(points, 0) AS points,
+ COALESCE(message_count, 0) AS message_count,
+ CASE
+ WHEN weekly_points_week = ? THEN COALESCE(weekly_points, 0)
+ ELSE 0
+ END AS weekly_points
+ FROM users
+ ORDER BY weekly_points DESC, points DESC, message_count DESC, telegram_id ASC
+ """,
+ (week_key,),
+ ).fetchall()
+
+ weekly_rank: Optional[int] = None
+ weekly_points = 0
+ for idx, row in enumerate(rows, start=1):
+ if str(row["supabase_key"] or "") == key:
+ weekly_rank = idx
+ weekly_points = int(row["weekly_points"] or 0)
+ break
+ return {
+ "weekly_points": max(0, int(weekly_points or 0)),
+ "weekly_rank": weekly_rank,
+ "total_ranked": len(rows),
+ }
diff --git a/web/app.py b/web/app.py
index c7a9028e..f61d2004 100644
--- a/web/app.py
+++ b/web/app.py
@@ -144,6 +144,21 @@ def _resolve_auth_points(request: Request) -> int:
return points
+def _resolve_weekly_profile(request: Request) -> Dict[str, Any]:
+ user_id = str(getattr(request.state, "auth_user_id", "") or "").strip()
+ if not user_id:
+ return {"weekly_points": 0, "weekly_rank": None}
+ try:
+ profile = _account_db.get_weekly_profile_by_supabase_user_id(user_id)
+ return {
+ "weekly_points": int(profile.get("weekly_points") or 0),
+ "weekly_rank": profile.get("weekly_rank"),
+ }
+ except Exception as exc:
+ logger.warning(f"auth weekly profile fallback failed user_id={user_id}: {exc}")
+ return {"weekly_points": 0, "weekly_rank": None}
+
+
def _assert_entitlement(request: Request) -> None:
if SUPABASE_ENTITLEMENT.enabled:
if _legacy_service_token_valid(request):
@@ -1117,12 +1132,15 @@ async def auth_me(request: Request):
subscription_active = None
points = _resolve_auth_points(request)
+ weekly_profile = _resolve_weekly_profile(request)
return {
"authenticated": bool(user_id),
"user_id": user_id,
"email": getattr(request.state, "auth_email", None),
"points": points,
+ "weekly_points": weekly_profile["weekly_points"],
+ "weekly_rank": weekly_profile["weekly_rank"],
"entitlement_mode": (
"supabase_required"
if SUPABASE_ENTITLEMENT.enabled and _SUPABASE_AUTH_REQUIRED