员工岗位可重新启用;调价认空运航线;会话存档跳号补拉;陆运报价按车型列回填

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
linmianxun
2026-10-28 19:48:47 +08:00
co-authored by Cursor
parent 2b528758b4
commit 56ba8e93b5
62 changed files with 2960 additions and 793 deletions
+134 -2
View File
@@ -1200,11 +1200,132 @@ def handle_group_file(
return "file_archived"
def _live_appchat_member_ids(client: Any, chat_id: str) -> list[str]:
"""
读企微应用群当前成员。主账名单过期时必须靠这个清人。
失败回空列表,不抛。不写主账。
"""
raw = (chat_id or "").strip()
if not raw:
return []
info_fn = getattr(client, "_appchat_info", None)
if not callable(info_fn):
return []
try:
info = info_fn(chat_id=raw) or {}
except Exception:
logger.exception("读应用群成员失败 chat=%s", raw)
return []
return [
str(x).strip()
for x in (info.get("userlist") or [])
if str(x).strip()
]
def _merge_dismiss_userids(*groups: list[str]) -> list[str]:
"""合并待移出名单,去重保序。"""
out: list[str] = []
seen: set[str] = set()
for group in groups:
for uid in group or []:
u = str(uid or "").strip()
if not u or u in seen:
continue
seen.add(u)
out.append(u)
return out
def dissolve_orphan_group(
*,
flow: Any,
chat_id: str,
sender_id: str = "",
) -> str:
"""
主账对不上工单时仍解散应用群。
老群、迁库丢绑定、虚拟转人工未写主账都会走到这里。
以企微当前成员为准移人;群名像工单号则尽量标协同结束。
不改六态。先回话再移人。
"""
room = (chat_id or "").strip()
if not room:
return "group_ignore"
client = group_client_of(flow)
info_fn = getattr(client, "_appchat_info", None)
info: dict[str, Any] = {}
if callable(info_fn):
try:
info = info_fn(chat_id=room) or {}
except Exception:
logger.exception("孤儿群读成员失败 chat=%s", room)
info = {}
members = _merge_dismiss_userids(
list(info.get("userlist") or []),
[sender_id] if (sender_id or "").strip() else [],
)
name = str(info.get("name") or "").strip()
no = ""
try:
from agent.policy import inquiry_copy as _copy
hit = str(_copy.extract_work_order_no(name) or "").strip()
if hit:
no = hit
elif name.upper().startswith(("WO", "VT")):
no = name.strip()
except Exception:
no = name if name.upper().startswith(("WO", "VT")) else ""
display_no = no or name or "-"
send_group_text(client, room, copy.group_dissolved(work_order_no=display_no))
dismiss = getattr(client, "dismiss_group", None)
dismiss_ok = False
if callable(dismiss) and members:
out = dismiss(chat_id=room, userids=members) or {}
dismiss_ok = bool(out.get("ok"))
if not dismiss_ok:
logger.warning(
"孤儿群移人失败 chat=%s err=%s members=%s",
room,
out.get("error"),
len(members),
)
elif not members:
logger.warning("孤儿群无成员可移 chat=%s name=%s", room, name or "-")
try:
from agent.channel.wshoto.rooms import unwatch_collab_room
unwatch_collab_room(room)
except Exception:
logger.exception("孤儿群取消存档监听失败 chat=%s", room)
if no:
ender = getattr(getattr(flow, "ledger", None), "end_collab_group", None)
if callable(ender):
try:
ender(work_order_no=no)
except Exception:
logger.exception("孤儿群标协同结束失败 wo=%s", no)
logger.info(
"orphan_dissolve chat=%s name=%s wo=%s members=%s dismiss_ok=%s by=%s",
room,
name or "-",
no or "-",
len(members),
dismiss_ok,
(sender_id or "")[:32],
)
return "group_dissolved"
def dissolve_group(*, flow: Any, ticket: object, sess: Any = None) -> str:
"""
解散应用群,这单协同结束,不改六态。
先发「群已解散」再移人:移完人销售可能已不在群,收不到确认。
移人名单 = 主账/书签成员 ∪ 企微当前成员,避免名单过期清不干净。
"""
view = ticket_view(ticket)
no = ticket_no(ticket)
@@ -1213,11 +1334,22 @@ def dissolve_group(*, flow: Any, ticket: object, sess: Any = None) -> str:
members = list(view.get("collab_member_ids") or view.get("memberIds") or [])
if sess is not None:
members = list(sess.invited_userids or members)
live = _live_appchat_member_ids(client, chat_id)
members = _merge_dismiss_userids(members, live)
# 先回话再移人,避免销售被移出后看不到确认。
send_group_text(client, chat_id, copy.group_dissolved(work_order_no=no))
dismiss = getattr(client, "dismiss_group", None)
if callable(dismiss) and chat_id:
dismiss(chat_id=chat_id, userids=members)
if callable(dismiss) and chat_id and members:
out = dismiss(chat_id=chat_id, userids=members) or {}
if not out.get("ok"):
logger.warning(
"解散群移人失败 chat=%s wo=%s err=%s",
chat_id,
no,
out.get("error"),
)
elif chat_id and not members:
logger.warning("解散群无成员可移 chat=%s wo=%s", chat_id, no)
if chat_id:
try:
from agent.channel.wshoto.rooms import unwatch_collab_room