Files

82 lines
3.5 KiB
Python

"""Replay committed chat operations under the current conversation identity."""
import hashlib
import json
def init_request_schema(connection):
connection.execute('''CREATE TABLE IF NOT EXISTS chat_request_results (
conv_id INTEGER NOT NULL, request_id TEXT NOT NULL, identity TEXT NOT NULL,
question TEXT NOT NULL, payload TEXT NOT NULL, message_id INTEGER NOT NULL,
quote_state TEXT, PRIMARY KEY(conv_id, request_id, identity))''')
connection.execute('''CREATE TRIGGER IF NOT EXISTS delete_chat_request_results
AFTER DELETE ON chat_history BEGIN
DELETE FROM chat_request_results WHERE conv_id=OLD.id;
END''')
def identity_key():
from .customer_service import current_customer_id, current_scope_key
from .visitor_service import visitor_id
return hashlib.sha256(json.dumps([visitor_id(), current_customer_id(), current_scope_key()]).encode()).hexdigest()
def existing_result(connection, conv_id, request_id, question):
if not request_id or not conv_id:
return None
row = connection.execute('SELECT question,payload,quote_state FROM chat_request_results '
'WHERE conv_id=? AND request_id=? AND identity=?', (conv_id, request_id, identity_key())).fetchone()
if row is None:
return None
if row[0] != question:
raise ValueError('请求标识已用于其他问题,请重新发送。')
if row[2]:
state = json.loads(row[2])
book = connection.execute('SELECT id FROM quote_books WHERE active=1 ORDER BY id DESC LIMIT 1').fetchone()
if state.get('book_id') != (book[0] if book else None):
raise ValueError('报价资料已更新,请按当前货物条件重新询价。')
return json.loads(row[1])
def replay_result(conv_id, request_id, question):
from .db import connect
from .visitor_service import owns_conversation
if not request_id or not conv_id or not owns_conversation(conv_id):
return None
connection = connect()
try:
return existing_result(connection, conv_id, request_id, question)
finally:
connection.close()
def login_quote_replay(conv_id, request_id, question):
"""Login may refresh orders while the original public quote edit stays applied."""
from .customer_service import current_customer_id
from .db import connect
from .visitor_service import owns_conversation
if not request_id or not current_customer_id() or not owns_conversation(conv_id):
return None
connection = connect()
try:
rows = connection.execute('SELECT payload,quote_state FROM chat_request_results '
'WHERE conv_id=? AND request_id=? AND question=? AND quote_state IS NOT NULL',
(conv_id, request_id, question))
for payload, state in rows:
if json.loads(payload).get('login_required'):
return json.loads(state)
return None
finally:
connection.close()
def remember_result(connection, conv_id, request_id, question, payload, message_id, quote_turn):
if not request_id:
return
if not isinstance(payload, dict):
raise ValueError('A completed response is required')
state = (quote_turn.candidate or getattr(quote_turn, 'replay_state', None)) if quote_turn else None
connection.execute('INSERT INTO chat_request_results VALUES(?,?,?,?,?,?,?)',
(conv_id, request_id, identity_key(), question, json.dumps(payload, ensure_ascii=False), message_id,
json.dumps(state, ensure_ascii=False) if state else None))