feat: 事件异常按工作日累计已过小时数

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-21 18:14:19 +08:00
co-authored by Cursor
parent 4381966c4e
commit ef0424a28f
2 changed files with 42 additions and 0 deletions
@@ -2,6 +2,7 @@
成交跟进纯规则:工作日顺延、线路对负责人。
本文件职责:给私聊/群聊成交共用,不发企微、不写主账。
也给事件异常算工作日已过小时数(非工作日整天不算;工作日当天 0–24 都算)。
禁止:在回调线程算完还同步推负责人;把六态写进本文件。
"""
@@ -105,6 +106,30 @@ def next_followup_at(now: datetime | None = None) -> datetime:
return datetime.combine(day, time(9, 0), tzinfo=SHANGHAI)
def workday_elapsed_hours(start: datetime, now: datetime) -> float:
"""
起止之间折合多少工作日小时。
非工作日整天不算;工作日当天 0–24 都算,不切上午晚上。
起点落在休息日:从下一个工作日 00:00 起算。
副作用:无。可在 Worker 巡检调用,禁止放进企微回调线程做 IO。
"""
a = start.astimezone(SHANGHAI) if start.tzinfo else start.replace(tzinfo=SHANGHAI)
b = now.astimezone(SHANGHAI) if now.tzinfo else now.replace(tzinfo=SHANGHAI)
if b <= a:
return 0.0
total = 0.0
cur = a
while cur.date() < b.date():
nxt = datetime.combine(cur.date() + timedelta(days=1), time(0, 0), tzinfo=SHANGHAI)
if is_workday(cur.date()):
total += (nxt - cur).total_seconds() / 3600.0
cur = nxt
if is_workday(b.date()):
total += (b - cur).total_seconds() / 3600.0
return total
def _split_routes(raw: str) -> list[str]:
out: list[str] = []
for part in (raw or "").replace(",", ",").replace("、", ",").split(","):