协商中再问按后台超时小时顺延并可强制清跟进时刻;工单与账号支持按筛选导出 Excel。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -50,6 +50,10 @@ def _reask_one(row: dict[str, Any], *, settings: Settings, ledger: Any = None) -
|
||||
no = str(row.get("work_order_no") or row.get("workOrderNo") or "").strip()
|
||||
if not no:
|
||||
return False
|
||||
# 进程/双 Worker 防重:同一工单同一天只发一轮(主账 next_followup 清不掉时曾连发 WO024)
|
||||
if _already_sent_reask(no, settings):
|
||||
logger.warning("协商再问去重跳过 wo=%s", no)
|
||||
return False
|
||||
chat_id = str(row.get("collab_chat_id") or row.get("collabChatId") or "").strip()
|
||||
sales = str(row.get("sales_wecom_id") or row.get("salesWecomId") or "").strip()
|
||||
name = str(row.get("sales_name") or row.get("salesName") or "").strip() or "销售"
|
||||
@@ -69,6 +73,7 @@ def _reask_one(row: dict[str, Any], *, settings: Settings, ledger: Any = None) -
|
||||
if not ok:
|
||||
logger.warning("协商再问原群失败且不补发私聊 wo=%s chat=%s", no, chat_id)
|
||||
return False
|
||||
_mark_sent_reask(no, settings)
|
||||
_start_deal_wait(ledger, no)
|
||||
return True
|
||||
if not sales:
|
||||
@@ -87,10 +92,47 @@ def _reask_one(row: dict[str, Any], *, settings: Settings, ledger: Any = None) -
|
||||
if not ok:
|
||||
logger.warning("协商再问私聊入队失败 wo=%s info=%s", no, info)
|
||||
return False
|
||||
_mark_sent_reask(no, settings)
|
||||
_start_deal_wait(ledger, no)
|
||||
return True
|
||||
|
||||
|
||||
def _already_sent_reask(work_order_no: str, settings: Settings) -> bool:
|
||||
"""
|
||||
跨进程去重:Redis SET NX。
|
||||
|
||||
返回 True=今天已发过应跳过;False=抢到发送权。
|
||||
主账 next_followup 若因 updateById 清不掉 null,没有这层会每分钟连发。
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from agent.policy.deal_followup import SHANGHAI
|
||||
from agent.redis_coord import get_redis_runtime
|
||||
from agent.redis_coord.idempotency import try_acquire
|
||||
|
||||
day = datetime.now(SHANGHAI).strftime("%Y-%m-%d")
|
||||
try:
|
||||
runtime = get_redis_runtime(settings)
|
||||
client = getattr(runtime, "client", None)
|
||||
if client is None:
|
||||
return False
|
||||
first = try_acquire(
|
||||
client,
|
||||
scope="deal_reask",
|
||||
idempotency_key=f"{work_order_no}:{day}",
|
||||
ttl_seconds=86400,
|
||||
)
|
||||
return not first
|
||||
except Exception:
|
||||
logger.exception("协商再问 Redis 去重失败 wo=%s", work_order_no)
|
||||
return False
|
||||
|
||||
|
||||
def _mark_sent_reask(work_order_no: str, settings: Settings) -> None:
|
||||
"""兼容旧调用点;去重键已在发送前 SET NX。"""
|
||||
_ = (work_order_no, settings)
|
||||
|
||||
|
||||
def _start_deal_wait(ledger: Any, work_order_no: str) -> None:
|
||||
"""再问发出后重新盯成交跟进。ledger 可空。"""
|
||||
from agent.policy.event_exception import WAIT_DEAL, start_wait
|
||||
|
||||
Reference in New Issue
Block a user