机器人显示名与站点标题可配;多段联运列表投影;协同群监听对账;工单附件落存;模板与工单后台补强

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
linmianxun
2026-10-19 09:41:59 +08:00
co-authored by Cursor
parent 277cdc1c28
commit 2b528758b4
119 changed files with 6760 additions and 3516 deletions
+63 -2
View File
@@ -130,6 +130,7 @@ class QuoteTests(unittest.TestCase):
self.assertEqual(phase, "multi_deal_sent")
self.assertEqual(self.sheets, ["SEA", "LAND"])
body = self.client.texts[-1]
self.assertTrue(body.startswith("@销售甲"), body)
self.assertIn("段1:海运", body)
self.assertIn("段2:陆运", body)
self.assertNotIn("180", body)
@@ -138,7 +139,8 @@ class QuoteTests(unittest.TestCase):
joined = " ".join(row["value"] for row in rows)
self.assertNotIn("180", joined)
def test_land_person_cannot_fill_sea_segment(self) -> None:
def test_fee_name_routes_to_matching_segment(self) -> None:
"""正文写海运费就归海运段,不看岗位是不是陆运。"""
phase = handle_multi_inbound(
flow=self.flow,
ticket=self.ticket,
@@ -148,7 +150,66 @@ class QuoteTests(unittest.TestCase):
sheet_fn=self.sheet,
)
self.assertEqual(phase, "segment_quoted")
self.assertEqual(self.sheets, ["LAND"])
self.assertEqual(self.sheets, ["SEA"])
def test_multi_file_archives_by_filename_mode(self) -> None:
"""多段 Excel 按文件名归段并落附件,不再回「没有识别到报价」。"""
from agent.policy.multi_group_ops import apply_multi_file
self.ledger.upsert_staff(
{"wecomId": "air1", "name": "航线甲", "roleCode": "air", "status": "active"}
)
# 改成陆运+空运两段,文件名含空运。
no = self.ticket.work_order_no
self.ledger.update_facts(
work_order_no=no,
facts={
"segments_json": json.dumps(
[
{"index": 1, "mode": "LAND", "facts": {"起运港": "北京"}},
{"index": 2, "mode": "AIR", "facts": {"目的港": "北宁"}},
],
ensure_ascii=False,
)
},
)
ticket = self.ledger.get_ticket(work_order_no=no)
phase = apply_multi_file(
flow=self.flow,
ticket=ticket,
chat_id="room-1",
sender_id="air1",
filename=f"{no}空运到港报价单.xlsx",
media={"media_id": "media-air-1"},
)
self.assertEqual(phase, "segment_quoted")
self.assertFalse(self.sheets)
self.assertTrue(any("报价附件已收到" in t for t in self.client.texts))
self.assertFalse(any("没有识别到报价" in t for t in self.client.texts))
def test_segment_index_beats_wrong_role(self) -> None:
"""岗位是空运,正文写段1陆运费 → 仍归陆运段,金额取 1000 不是段号 1。"""
from agent.llm.extract_text import extract_product_quote
from agent.policy.multi_group_ops import resolve_quote_segment
from agent.policy.multi_segments import Segment
segs = [
Segment(index=1, mode="LAND", facts={}),
Segment(index=2, mode="AIR", facts={}),
]
target, reason = resolve_quote_segment("段1:陆运费 CNY1000", segs, "AIR")
self.assertIsNotNone(target)
assert target is not None
self.assertEqual(target.mode, "LAND")
self.assertEqual(target.index, 1)
self.assertTrue(reason.startswith("text_index"))
quote = extract_product_quote(
"@智价通AIQ 段1:陆运费 CNY1000",
business_line="LAND",
transport_mode="陆运",
)
self.assertEqual(float(quote.get("total") or 0), 1000.0)
self.assertEqual(str((quote.get("fee_rows") or [{}])[0].get("name") or ""), "陆运费")
def test_requote_refreshes_deal(self) -> None:
handle_multi_inbound(