|
|
@@ -7,6 +7,7 @@ demand_find_task: 执行记录表,通过 demand_content_id 关联
|
|
|
|
|
|
import logging
|
|
|
from datetime import datetime
|
|
|
+from decimal import Decimal
|
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
|
|
from .connection import get_connection
|
|
|
@@ -127,6 +128,69 @@ def get_latest_demand_task_oprate_is_open() -> Optional[int]:
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
+def get_latest_day_limit_coast() -> Optional[Decimal]:
|
|
|
+ """
|
|
|
+ 读取 demand_task_oprate 中按 update_time 最新的一行的 day_limit_coast。
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ Decimal(两位小数) 或 None(无记录或字段为空)
|
|
|
+ """
|
|
|
+ sql = """
|
|
|
+ SELECT day_limit_coast
|
|
|
+ FROM demand_task_oprate
|
|
|
+ ORDER BY update_time DESC, id DESC
|
|
|
+ LIMIT 1
|
|
|
+ """
|
|
|
+ conn = None
|
|
|
+ try:
|
|
|
+ conn = get_connection()
|
|
|
+ with conn.cursor() as cur:
|
|
|
+ cur.execute(sql)
|
|
|
+ row = cur.fetchone()
|
|
|
+ if not row:
|
|
|
+ return None
|
|
|
+ val = row.get("day_limit_coast")
|
|
|
+ if val is None:
|
|
|
+ return None
|
|
|
+ return Decimal(str(val))
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"get_latest_day_limit_coast 失败: {e}", exc_info=True)
|
|
|
+ raise
|
|
|
+ finally:
|
|
|
+ if conn:
|
|
|
+ conn.close()
|
|
|
+
|
|
|
+
|
|
|
+def get_total_token_coast_between(start_time: datetime, end_time: datetime) -> Decimal:
|
|
|
+ """
|
|
|
+ 统计 demand_find_task 在指定时间区间内的 token_coast 总和(基于 created_at 字段)。
|
|
|
+
|
|
|
+ start_time <= created_at < end_time
|
|
|
+ """
|
|
|
+ sql = """
|
|
|
+ SELECT COALESCE(SUM(token_coast), 0) AS total_coast
|
|
|
+ FROM demand_find_task
|
|
|
+ WHERE created_at >= %s
|
|
|
+ AND created_at < %s
|
|
|
+ """
|
|
|
+ conn = None
|
|
|
+ try:
|
|
|
+ conn = get_connection()
|
|
|
+ with conn.cursor() as cur:
|
|
|
+ cur.execute(sql, (start_time, end_time))
|
|
|
+ row = cur.fetchone() or {}
|
|
|
+ val = row.get("total_coast") if row is not None else None
|
|
|
+ if val is None:
|
|
|
+ return Decimal("0")
|
|
|
+ return Decimal(str(val))
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"get_total_token_coast_between 失败: {e}", exc_info=True)
|
|
|
+ raise
|
|
|
+ finally:
|
|
|
+ if conn:
|
|
|
+ conn.close()
|
|
|
+
|
|
|
+
|
|
|
def get_one_today_unprocessed_demand(*, dt: int) -> Optional[Dict[str, Any]]:
|
|
|
"""
|
|
|
从 demand_content 中取「当天 dt」且尚未在 demand_find_task 中出现过的 1 条需求。
|
|
|
@@ -250,24 +314,43 @@ def create_task_record(demand_content_id: int, trace_id: str = "", status: int =
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
-def update_task_on_complete(demand_content_id: int, trace_id: str, status: int) -> None:
|
|
|
+def update_task_on_complete(
|
|
|
+ demand_content_id: int,
|
|
|
+ trace_id: str,
|
|
|
+ status: int,
|
|
|
+ token_coast: Optional[Decimal] = None,
|
|
|
+) -> None:
|
|
|
"""
|
|
|
任务完成后更新 trace_id 和 status。
|
|
|
匹配 trace_id 为空字符串的记录(初始创建时的占位)。
|
|
|
"""
|
|
|
sql = """
|
|
|
UPDATE demand_find_task
|
|
|
- SET trace_id = %s, status = %s
|
|
|
- WHERE demand_content_id = %s AND trace_id = ''
|
|
|
+ SET trace_id = %s,
|
|
|
+ status = %s
|
|
|
"""
|
|
|
+ params: list[Any] = [trace_id, status]
|
|
|
+
|
|
|
+ if token_coast is not None:
|
|
|
+ sql += ", token_coast = %s\n"
|
|
|
+ params.append(token_coast)
|
|
|
+
|
|
|
+ sql += "WHERE demand_content_id = %s AND trace_id = ''"
|
|
|
+ params.append(demand_content_id)
|
|
|
conn = None
|
|
|
try:
|
|
|
conn = get_connection()
|
|
|
with conn.cursor() as cur:
|
|
|
- cur.execute(sql, (trace_id, status, demand_content_id))
|
|
|
- logger.info(f"更新任务完成: demand_content_id={demand_content_id}, trace_id={trace_id}, status={status}")
|
|
|
+ cur.execute(sql, tuple(params))
|
|
|
+ logger.info(
|
|
|
+ "更新任务完成: demand_content_id=%s, trace_id=%s, status=%s, token_coast=%s",
|
|
|
+ demand_content_id,
|
|
|
+ trace_id,
|
|
|
+ status,
|
|
|
+ token_coast,
|
|
|
+ )
|
|
|
except Exception as e:
|
|
|
- logger.error(f"update_task_on_complete 失败: {e}", exc_info=True)
|
|
|
+ logger.error("update_task_on_complete 失败: %s", e, exc_info=True)
|
|
|
raise
|
|
|
finally:
|
|
|
if conn:
|