188 lines
6.5 KiB
Python
188 lines
6.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
复聊配置 API(需要登录):
|
||
- GET /api/followup-configs -> 查询复聊配置列表
|
||
- POST /api/followup-configs -> 创建复聊配置
|
||
- GET /api/followup-configs/{id} -> 查询单个配置
|
||
- PUT /api/followup-configs/{id} -> 更新配置
|
||
- DELETE /api/followup-configs/{id} -> 删除配置
|
||
|
||
- GET /api/followup-scripts -> 查询话术列表
|
||
- POST /api/followup-scripts -> 创建话术
|
||
- GET /api/followup-scripts/{id} -> 查询单个话术
|
||
- PUT /api/followup-scripts/{id} -> 更新话术
|
||
- DELETE /api/followup-scripts/{id} -> 删除话术
|
||
|
||
- GET /api/followup-records -> 查询复聊记录
|
||
- POST /api/followup-records/send -> 手动发送复聊消息
|
||
"""
|
||
from rest_framework import status
|
||
from rest_framework.decorators import api_view
|
||
|
||
from server.core.response import api_success, api_error
|
||
from server.models import FollowUpConfig, FollowUpScript, FollowUpRecord, ContactRecord
|
||
from server.serializers import (
|
||
FollowUpConfigSerializer,
|
||
FollowUpScriptSerializer,
|
||
FollowUpRecordSerializer
|
||
)
|
||
|
||
|
||
# ────────────────────────── 复聊配置 ──────────────────────────
|
||
|
||
@api_view(["GET", "POST"])
|
||
def followup_config_list(request):
|
||
"""复聊配置列表。"""
|
||
if request.method == "GET":
|
||
position = request.query_params.get("position")
|
||
is_active = request.query_params.get("is_active")
|
||
|
||
qs = FollowUpConfig.objects.all()
|
||
if position:
|
||
qs = qs.filter(position__icontains=position)
|
||
if is_active is not None:
|
||
qs = qs.filter(is_active=is_active.lower() in ("true", "1"))
|
||
|
||
configs = qs.order_by("-created_at")
|
||
return api_success(FollowUpConfigSerializer(configs, many=True).data)
|
||
|
||
# POST
|
||
ser = FollowUpConfigSerializer(data=request.data)
|
||
ser.is_valid(raise_exception=True)
|
||
ser.save()
|
||
return api_success(ser.data, http_status=status.HTTP_201_CREATED)
|
||
|
||
|
||
@api_view(["GET", "PUT", "DELETE"])
|
||
def followup_config_detail(request, pk):
|
||
"""复聊配置详情。"""
|
||
try:
|
||
obj = FollowUpConfig.objects.get(pk=pk)
|
||
except FollowUpConfig.DoesNotExist:
|
||
return api_error(status.HTTP_404_NOT_FOUND, "复聊配置不存在")
|
||
|
||
if request.method == "GET":
|
||
return api_success(FollowUpConfigSerializer(obj).data)
|
||
|
||
if request.method == "PUT":
|
||
ser = FollowUpConfigSerializer(obj, data=request.data, partial=True)
|
||
ser.is_valid(raise_exception=True)
|
||
ser.save()
|
||
return api_success(ser.data)
|
||
|
||
# DELETE
|
||
obj.delete()
|
||
return api_success(msg="复聊配置已删除")
|
||
|
||
|
||
# ────────────────────────── 复聊话术 ──────────────────────────
|
||
|
||
@api_view(["GET", "POST"])
|
||
def followup_script_list(request):
|
||
"""复聊话术列表。"""
|
||
if request.method == "GET":
|
||
config_id = request.query_params.get("config_id")
|
||
day_number = request.query_params.get("day_number")
|
||
|
||
qs = FollowUpScript.objects.all()
|
||
if config_id:
|
||
qs = qs.filter(config_id=config_id)
|
||
if day_number is not None:
|
||
qs = qs.filter(day_number=day_number)
|
||
|
||
scripts = qs.order_by("config_id", "day_number", "order")
|
||
return api_success(FollowUpScriptSerializer(scripts, many=True).data)
|
||
|
||
# POST
|
||
ser = FollowUpScriptSerializer(data=request.data)
|
||
ser.is_valid(raise_exception=True)
|
||
ser.save()
|
||
return api_success(ser.data, http_status=status.HTTP_201_CREATED)
|
||
|
||
|
||
@api_view(["GET", "PUT", "DELETE"])
|
||
def followup_script_detail(request, pk):
|
||
"""复聊话术详情。"""
|
||
try:
|
||
obj = FollowUpScript.objects.get(pk=pk)
|
||
except FollowUpScript.DoesNotExist:
|
||
return api_error(status.HTTP_404_NOT_FOUND, "复聊话术不存在")
|
||
|
||
if request.method == "GET":
|
||
return api_success(FollowUpScriptSerializer(obj).data)
|
||
|
||
if request.method == "PUT":
|
||
ser = FollowUpScriptSerializer(obj, data=request.data, partial=True)
|
||
ser.is_valid(raise_exception=True)
|
||
ser.save()
|
||
return api_success(ser.data)
|
||
|
||
# DELETE
|
||
obj.delete()
|
||
return api_success(msg="复聊话术已删除")
|
||
|
||
|
||
# ────────────────────────── 复聊记录 ──────────────────────────
|
||
|
||
@api_view(["GET"])
|
||
def followup_record_list(request):
|
||
"""复聊记录列表。"""
|
||
contact_id = request.query_params.get("contact_id")
|
||
config_id = request.query_params.get("config_id")
|
||
got_reply = request.query_params.get("got_reply")
|
||
page = int(request.query_params.get("page", 1))
|
||
page_size = int(request.query_params.get("page_size", 20))
|
||
|
||
qs = FollowUpRecord.objects.all()
|
||
if contact_id:
|
||
qs = qs.filter(contact_id=contact_id)
|
||
if config_id:
|
||
qs = qs.filter(config_id=config_id)
|
||
if got_reply is not None:
|
||
qs = qs.filter(got_reply=got_reply.lower() in ("true", "1"))
|
||
|
||
total = qs.count()
|
||
start = (page - 1) * page_size
|
||
end = start + page_size
|
||
records = qs[start:end]
|
||
|
||
return api_success({
|
||
"total": total,
|
||
"page": page,
|
||
"page_size": page_size,
|
||
"results": FollowUpRecordSerializer(records, many=True).data,
|
||
})
|
||
|
||
|
||
@api_view(["POST"])
|
||
def followup_send_manual(request):
|
||
"""手动发送复聊消息。"""
|
||
contact_id = request.data.get("contact_id")
|
||
content = request.data.get("content", "").strip()
|
||
|
||
if not contact_id:
|
||
return api_error(status.HTTP_400_BAD_REQUEST, "请提供 contact_id")
|
||
if not content:
|
||
return api_error(status.HTTP_400_BAD_REQUEST, "请提供发送内容")
|
||
|
||
try:
|
||
contact = ContactRecord.objects.get(pk=contact_id)
|
||
except ContactRecord.DoesNotExist:
|
||
return api_error(status.HTTP_404_NOT_FOUND, "联系人不存在")
|
||
|
||
# TODO: 这里需要调用浏览器自动化发送消息
|
||
# 暂时只记录到数据库
|
||
|
||
record = FollowUpRecord.objects.create(
|
||
contact_id=contact_id,
|
||
config_id=0, # 手动发送
|
||
script_id=0, # 手动发送
|
||
day_number=0,
|
||
content=content,
|
||
)
|
||
|
||
return api_success({
|
||
"record": FollowUpRecordSerializer(record).data,
|
||
"message": "复聊消息已发送"
|
||
})
|