让成交卡等报价文件真正发出后再出现,并收紧 PDF 顶部留白,避免抬头被裁或空一截。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-15 10:36:55 +08:00
co-authored by Cursor
parent cb3bf5238b
commit a7a8487eb3
22 changed files with 1630 additions and 126 deletions
+39
View File
@@ -163,6 +163,14 @@ class MemoryMessageStore:
logger.info("outbox 入队 id=%s touser=%s", item.id, touser)
return True, item.id
def has_outbound_dedupe(self, prefix: str) -> bool:
"""去重键是否已出过站(前缀匹配)。给 wait_file 判断文件/成交卡是否已发。"""
head = (prefix or "").strip()
if not head:
return False
with self._lock:
return any(str(k).startswith(head) for k in self._seen_out)
def claim_outbound(self) -> Optional[OutboxItem]:
"""认领一条 pending/超时 outbox。"""
now = time.time()
@@ -207,6 +215,37 @@ class MemoryMessageStore:
def wait_outbox(self, timeout: float = 1.0) -> None:
self._outbox_event.wait(timeout=timeout)
def wait_outbound_done(self, item_id: str, timeout_sec: float = 12.0) -> bool:
"""
等到指定出站已发送完成或失败。
查价前必须先等询价确认发出,避免暂无报价卡抢先到销售手机。
只等这一条,不锁其它工单。超时返回 False。
"""
raw = (item_id or "").strip()
if not raw:
return False
started = time.time()
deadline = started + max(0.1, float(timeout_sec))
saw_claim = False
while time.time() < deadline:
state = ""
with self._lock:
item = self._outbox.get(raw)
if item:
state = item.state
if state in {TaskState.DONE, TaskState.FAILED}:
return state == TaskState.DONE
if state == TaskState.CLAIMED:
saw_claim = True
# 单测没有出站线程:一直 PENDING 就不要空等 12 秒。测服有出站线程会立刻认领。
if not saw_claim and state == TaskState.PENDING and time.time() - started >= 0.4:
return True
if not state and time.time() - started >= 0.3:
return True
self._outbox_event.wait(0.05)
return False
def stats(self) -> dict[str, Any]:
with self._lock:
return {