feat: 指定单打手响应查询与提交接口

新增 zdcx/zdhf 接口及订单表指定响应字段,供抢单页想接/不想接/等会接。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-29 05:51:25 +08:00
parent 0de3c164fb
commit 31247b7915
4 changed files with 191 additions and 2 deletions

View File

@@ -0,0 +1,39 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0013_fakegrabordershufflestate_ordersequence'),
]
operations = [
migrations.AddField(
model_name='order',
name='AssignedResponse',
field=models.PositiveSmallIntegerField(
blank=True, null=True,
db_column='zhiding_hf',
verbose_name='指定打手响应 1想接 2不想接 3等会接',
),
),
migrations.AddField(
model_name='order',
name='AssignedResponseAt',
field=models.DateTimeField(
blank=True, null=True,
db_column='zhiding_hf_sj',
verbose_name='指定响应时间',
),
),
migrations.AddField(
model_name='order',
name='AssignedLaterNote',
field=models.CharField(
blank=True, default='',
max_length=100,
db_column='zhiding_dhj_sm',
verbose_name='等会接说明',
),
),
]

View File

@@ -81,6 +81,18 @@ class Order(QModel):
max_length=32, null=True, blank=True,
db_column='zhiding_id', verbose_name='指定ID',
)
AssignedResponse = models.PositiveSmallIntegerField(
null=True, blank=True,
db_column='zhiding_hf', verbose_name='指定打手响应 1想接 2不想接 3等会接',
)
AssignedResponseAt = models.DateTimeField(
null=True, blank=True,
db_column='zhiding_hf_sj', verbose_name='指定响应时间',
)
AssignedLaterNote = models.CharField(
max_length=100, blank=True, default='',
db_column='zhiding_dhj_sm', verbose_name='等会接说明',
)
ProductID = models.IntegerField(
null=True, blank=True,
db_column='shangpin_id', verbose_name='商品ID',

View File

@@ -10,7 +10,8 @@ from .views import CreateOrderView, WechatPayNotifyView, \
AdGengHuanDaShou,ShangjiaCOSZhengshuView, DashouHuoquLeixingView,AdJuJueJieSuan, AdZhuanYiDaTing, AdQuXiaoZhiDing,DashouXiugaiView,DaiLiQunLiaoXiaoXiView,\
ShangjiaLianjieLiuYanZhuanFaView, DingdanXiangqingView2, JiedanView2, ZxsjghdsView, \
ShangjiaFakuanApplyView, ShangjiaFakuaiXiugaiView, ShangjiaShujuTongjiView, LianTongDuiHuaZhunBeiView, \
LianTongPeiDuiDingDanLieBiaoView, LianTongDingDanZhuangTaiView, LianTongDingDanZhuangTaiPiLiangView
LianTongPeiDuiDingDanLieBiaoView, LianTongDingDanZhuangTaiView, LianTongDingDanZhuangTaiPiLiangView, \
ZhiDingChaxunView, ZhiDingHuiFuView
urlpatterns = [
@@ -36,6 +37,8 @@ urlpatterns = [
# 获取订单列表
path('ddhq', DashouDingdanHuoquView.as_view(), name='打手抢单页获取订单'),
path('zdcx', ZhiDingChaxunView.as_view(), name='查询被指定订单'),
path('zdhf', ZhiDingHuiFuView.as_view(), name='指定订单打手响应'),
path('qiangdan', QiangdanView.as_view(), name='打手抢单'),
path('dsscpz', DashouCOSZhengshuView.as_view(), name='打手上传图片OSS参数获取接口'),
# 打手提交订单完成接口

View File

@@ -82,6 +82,9 @@ from config.models import (
logger = logging.getLogger(__name__)
ZHIDING_HF_TEXT = {1: '想接', 2: '不想接', 3: '等会接'}
class PaymentFailView(APIView):
"""
前端支付失败接口 - 处理用户主动取消或支付失败
@@ -3104,7 +3107,8 @@ class DashouDingdanHuoquView(APIView):
MerchantNickname=Subquery(shangjia_sub)
).values(
'OrderID', 'Status', 'Platform', 'PlayerCommission',
'AssignedID', 'ProductTypeID', 'ImageURL', 'GrabRequirement',
'AssignedID', 'AssignedResponse', 'AssignedResponseAt', 'AssignedLaterNote',
'ProductTypeID', 'ImageURL', 'GrabRequirement',
'MembershipID', 'CommissionReq', 'Description', 'Remark', 'CreateTime',
'MerchantNickname'
)
@@ -3279,6 +3283,10 @@ class DashouDingdanHuoquView(APIView):
'zhiding_uid': order['AssignedID'] or '',
'zhiding_avatar': info.get('avatar', ''),
'zhiding_nicheng': info.get('nicheng', ''),
'zhiding_hf': order.get('AssignedResponse'),
'zhiding_hf_text': ZHIDING_HF_TEXT.get(order.get('AssignedResponse'), ''),
'zhiding_dhj_sm': order.get('AssignedLaterNote') or '',
'zhiding_hf_sj': fmt_datetime(order['AssignedResponseAt']) if order.get('AssignedResponseAt') else '',
# 三层标签
'xuqiu_biaoqian': xuqiu_tags_map.get(oid, []),
'dashou_biaoqian': dashou_tags_map.get(oid, []),
@@ -6317,6 +6325,133 @@ class AdQuXiaoZhiDing(APIView):
)
class ZhiDingChaxunView(APIView):
"""
查询当前打手被指定的待接订单
POST /dingdan/zdcx
"""
permission_classes = [IsAuthenticated]
def post(self, request):
try:
dashou_uid = str(request.user.UserUID)
try:
dashou_profile = request.user.DashouProfile
if dashou_profile.zhanghaozhuangtai != 1:
return Response({'code': 403, 'msg': '账号状态异常'}, status=403)
except Exception:
return Response({'code': 403, 'msg': '您不是打手'}, status=403)
orders = Order.query.filter(
Status=7,
AssignedID=dashou_uid,
).filter(
Q(PlayerID__isnull=True) | Q(PlayerID='')
).order_by('-CreateTime')[:20]
result = []
for o in orders:
hf = getattr(o, 'AssignedResponse', None)
result.append({
'dingdan_id': o.OrderID,
'zhuangtai': o.Status,
'pingtai': o.Platform,
'dashou_fencheng': float(o.PlayerCommission or 0),
'leixing_id': o.ProductTypeID or 0,
'tupian': o.ImageURL or '',
'jieshao': o.Description or '',
'beizhu': o.Remark or '',
'creat_time': fmt_datetime(o.CreateTime),
'create_time': fmt_datetime(o.CreateTime),
'zhiding_uid': o.AssignedID or '',
'zhiding_hf': hf,
'zhiding_hf_text': ZHIDING_HF_TEXT.get(hf, ''),
'zhiding_dhj_sm': getattr(o, 'AssignedLaterNote', '') or '',
'zhiding_hf_sj': fmt_datetime(o.AssignedResponseAt) if getattr(o, 'AssignedResponseAt', None) else '',
'yaoqiuleixing': o.GrabRequirement or 0,
'huiyuan_id': o.MembershipID or '',
'yajin': float(o.CommissionReq or 0),
})
return Response({
'code': 200,
'msg': '获取成功',
'data': {'list': result, 'count': len(result)},
})
except Exception as e:
logger.error(f"指定订单查询失败: {e}", exc_info=True)
return Response({'code': 500, 'msg': '服务器内部错误'}, status=500)
class ZhiDingHuiFuView(APIView):
"""
指定单打手响应:想接 / 不想接 / 等会接
POST /dingdan/zdhf
参数: dingdan_id, huifu (1|2|3), deng_hui_note (等会接说明,可选)
"""
permission_classes = [IsAuthenticated]
def post(self, request):
try:
data = request.data
dingdan_id = str(data.get('dingdan_id') or data.get('OrderID') or '').strip()
huifu = int(data.get('huifu') or 0)
deng_hui_note = str(data.get('deng_hui_note') or '').strip()[:100]
if not dingdan_id:
return Response({'code': 400, 'msg': '订单ID不能为空'}, status=400)
if huifu not in (1, 2, 3):
return Response({'code': 400, 'msg': '无效的响应类型'}, status=400)
if huifu == 3 and not deng_hui_note:
return Response({'code': 400, 'msg': '请填写预计接待时间'}, status=400)
dashou_uid = str(request.user.UserUID)
with transaction.atomic():
try:
order = Order.query.select_for_update().get(OrderID=dingdan_id)
except Order.DoesNotExist:
return Response({'code': 404, 'msg': '订单不存在'}, status=404)
if order.Status != 7:
return Response({'code': 400, 'msg': '订单已不是指定中状态'}, status=400)
if str(order.AssignedID or '') != dashou_uid:
return Response({'code': 403, 'msg': '您不是该订单的指定打手'}, status=403)
if order.PlayerID:
return Response({'code': 400, 'msg': '订单已被接单'}, status=400)
now = timezone.now()
order.AssignedResponse = huifu
order.AssignedResponseAt = now
if huifu == 2:
order.Status = 1
order.AssignedID = None
order.AssignedLaterNote = ''
elif huifu == 3:
order.AssignedLaterNote = deng_hui_note
else:
order.AssignedLaterNote = ''
order.save()
msg_map = {1: '已标记想接,请点击接待完成接单', 2: '已婉拒,订单已退回大厅', 3: '已记录,请按时接待'}
return Response({
'code': 200,
'msg': msg_map.get(huifu, '操作成功'),
'data': {
'dingdan_id': dingdan_id,
'huifu': huifu,
'huifu_text': ZHIDING_HF_TEXT.get(huifu, ''),
},
})
except Exception as e:
logger.error(f"指定订单响应失败: {e}", exc_info=True)
return Response({'code': 500, 'msg': '服务器内部错误'}, status=500)
class DashouXiugaiView(APIView):
"""
打手修改订单交付内容接口