134 lines
4.4 KiB
Python
134 lines
4.4 KiB
Python
# peizhi/views_huashu.py — 小程序话术查询与自动回复匹配
|
|
import json
|
|
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework import status
|
|
|
|
from .models import HuashuConfig
|
|
|
|
|
|
def _serialize_huashu_item(item):
|
|
return {
|
|
'id': item.id,
|
|
'scene_key': item.scene_key,
|
|
'item_type': item.item_type,
|
|
'title': item.title,
|
|
'content': item.content,
|
|
'confirm_text': item.confirm_text,
|
|
'cancel_text': item.cancel_text,
|
|
'keywords': item.keywords or [],
|
|
'match_mode': item.match_mode,
|
|
'priority': item.priority,
|
|
'is_active': item.is_active,
|
|
'sort_order': item.sort_order,
|
|
}
|
|
|
|
|
|
def _match_auto_reply(user_text, queryset):
|
|
text = (user_text or '').strip().lower()
|
|
if not text:
|
|
return None
|
|
|
|
for item in queryset:
|
|
keywords = item.keywords or []
|
|
if not isinstance(keywords, list):
|
|
try:
|
|
keywords = json.loads(keywords) if keywords else []
|
|
except (TypeError, ValueError):
|
|
keywords = []
|
|
|
|
for kw in keywords:
|
|
kw_norm = str(kw).strip().lower()
|
|
if not kw_norm:
|
|
continue
|
|
if item.match_mode == HuashuConfig.MATCH_EXACT and text == kw_norm:
|
|
return item
|
|
if item.match_mode == HuashuConfig.MATCH_CONTAINS and kw_norm in text:
|
|
return item
|
|
return None
|
|
|
|
|
|
class HuashuQueryView(APIView):
|
|
"""
|
|
批量获取话术配置
|
|
POST /peizhi/huashuhq
|
|
请求: { "scene_keys": ["chat_image_confirm", "cs_welcome"] }
|
|
"""
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def post(self, request):
|
|
scene_keys = request.data.get('scene_keys') or []
|
|
if not isinstance(scene_keys, list) or not scene_keys:
|
|
return Response({'code': 400, 'msg': '缺少参数 scene_keys'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
allowed = {c[0] for c in HuashuConfig.SCENE_CHOICES}
|
|
result = {}
|
|
|
|
for scene_key in scene_keys:
|
|
if scene_key not in allowed:
|
|
continue
|
|
|
|
if scene_key == HuashuConfig.SCENE_CS_AUTO_REPLY:
|
|
items = HuashuConfig.objects.filter(
|
|
scene_key=scene_key,
|
|
item_type=HuashuConfig.ITEM_AUTO_REPLY,
|
|
is_active=True,
|
|
).order_by('-priority', 'sort_order', 'id')
|
|
result[scene_key] = {
|
|
'item_type': HuashuConfig.ITEM_AUTO_REPLY,
|
|
'items': [_serialize_huashu_item(i) for i in items],
|
|
}
|
|
else:
|
|
item = HuashuConfig.objects.filter(
|
|
scene_key=scene_key,
|
|
is_active=True,
|
|
).order_by('-priority', 'sort_order', 'id').first()
|
|
if item:
|
|
result[scene_key] = _serialize_huashu_item(item)
|
|
else:
|
|
result[scene_key] = None
|
|
|
|
return Response({'code': 200, 'msg': '获取成功', 'data': result})
|
|
|
|
|
|
class HuashuMatchView(APIView):
|
|
"""
|
|
客服自动回复关键词匹配
|
|
POST /peizhi/huashu_match
|
|
请求: { "scene_key": "cs_auto_reply", "user_text": "怎么退款" }
|
|
"""
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def post(self, request):
|
|
scene_key = request.data.get('scene_key', HuashuConfig.SCENE_CS_AUTO_REPLY)
|
|
user_text = request.data.get('user_text', '')
|
|
|
|
if scene_key != HuashuConfig.SCENE_CS_AUTO_REPLY:
|
|
return Response({'code': 400, 'msg': 'scene_key 仅支持 cs_auto_reply'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
queryset = HuashuConfig.objects.filter(
|
|
scene_key=scene_key,
|
|
item_type=HuashuConfig.ITEM_AUTO_REPLY,
|
|
is_active=True,
|
|
).order_by('-priority', 'sort_order', 'id')
|
|
|
|
matched = _match_auto_reply(user_text, queryset)
|
|
if matched:
|
|
return Response({
|
|
'code': 200,
|
|
'msg': '匹配成功',
|
|
'data': {
|
|
'matched': True,
|
|
'content': matched.content,
|
|
'rule_id': matched.id,
|
|
},
|
|
})
|
|
|
|
return Response({
|
|
'code': 200,
|
|
'msg': '未匹配',
|
|
'data': {'matched': False, 'content': '', 'rule_id': None},
|
|
})
|