支持免登录游客聊天并隔离历史与附件

This commit is contained in:
2026-10-30 12:17:43 +08:00
parent e58dd86d5b
commit 147edd042f
36 changed files with 663 additions and 129 deletions
+16 -3
View File
@@ -7,6 +7,7 @@ from datetime import datetime
from .config import get_setting
from .order_tracking import build_tracking
from .visitor_service import customer_tenant_id
FIELDS = ('source_order_id', 'tenant_id', 'order_no', 'inbound_code', 'shipment_id',
@@ -22,6 +23,7 @@ FIELD_LABELS = {'inbound':'入仓码', 'shipment':'Shipment ID', 'country':'目
'parent':'父订单号', 'updated':'来源更新时间'}
IDENTIFIER = re.compile(r'(?<![A-Za-z0-9_-])[A-Za-z0-9][A-Za-z0-9_-]{5,63}(?![A-Za-z0-9_-])')
ORDER_DETAIL = r'状态|进度|轨迹|到哪|开船|到港|清关|提柜|还柜|签收|预计|什么时候|何时|多久|重量|毛重|体积|件数|箱数|目的地|目的国|目的仓|仓库|父订单|运费|费用|价格|几件|几箱|公斤|千克|多少钱'
ORDER_LOGIN_TEXT = '订单查询将在客户账号登录并关联后开放。您可以先咨询运费、时效,或联系人工客服。'
class OrderDataUnavailable(Exception):
@@ -110,7 +112,7 @@ def import_tracking_records(connection, records, replace=False):
return {'imported': imported, 'preserved': preserved, 'missing': missing}
def lookup_order(reference):
def lookup_order(reference, tenant_id=None):
"""Exact, bounded lookup; scope comes from server configuration, never model SQL."""
from .db import connect
@@ -120,6 +122,12 @@ def lookup_order(reference):
query = 'SELECT * FROM order_test_data WHERE (order_no=? OR inbound_code=? OR shipment_id=?)'
values = [reference] * 3
tenant = get_setting('ORDER_DATA_TENANT_ID')
if tenant_id is not None:
if not str(tenant_id).strip():
return []
if tenant and str(tenant_id) != str(tenant):
return []
tenant = str(tenant_id)
if tenant:
query += ' AND tenant_id=?'
values.append(str(tenant))
@@ -210,6 +218,9 @@ def is_order_followup(message):
def answer_query(message, conv_id):
references = extract_reference(message)
tenant = customer_tenant_id()
if references and tenant is None:
return {'t': ORDER_LOGIN_TEXT}
if len(references) > 1:
return {'t':'请一次提供一个订单号、入仓码或 Shipment ID,避免查错订单。'}
reference = references[0] if references else None
@@ -238,10 +249,12 @@ def answer_query(message, conv_id):
pass
if not reference:
if re.search(r'查.*(?:订单|运单|物流轨迹)|订单状态|物流轨迹|shipment\s*id|(?:列出|搜索|所有|全部|多少).*(?:订单|入仓)|订单.*(?:多少|列表)', message, re.I):
return {'t':'请提供订单号、入仓码或 Shipment ID。'}
return {'t':ORDER_LOGIN_TEXT if tenant is None else '请提供订单号、入仓码或 Shipment ID。'}
return None
if tenant is None:
return {'t': ORDER_LOGIN_TEXT}
try:
matches = lookup_order(reference)
matches = lookup_order(reference, tenant_id=tenant)
except OrderDataUnavailable:
return {'t':'订单信息暂时无法读取,请稍后重试。'}
if not matches: