feat: 抢单池/组队角标计数多接口附加字段(兼容旧客户端)
This commit is contained in:
100
orders/services/dashou_badges.py
Normal file
100
orders/services/dashou_badges.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""打手端角标计数:抢单池按类型待接单数、组队大厅待加入数。
|
||||
|
||||
仅供响应附加字段,不改变原有业务筛选逻辑。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from django.db.models import Count
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def grab_pool_type_pending_counts(club_id: str) -> dict[str, int]:
|
||||
"""
|
||||
与 /dingdan/ddhq 同口径:Status in (1,7) + 抢单俱乐部范围,按 ProductTypeID 聚合。
|
||||
返回 { \"类型id\": 数量 },key 一律 str,方便 JSON / 前端。
|
||||
"""
|
||||
club_id = (club_id or '').strip()
|
||||
if not club_id:
|
||||
return {}
|
||||
try:
|
||||
from django.db.models import Q
|
||||
from orders.models import Order
|
||||
from jituan.services.order_grab_share import order_club_q_for_grabber
|
||||
|
||||
base = Q(Status__in=[1, 7]) & order_club_q_for_grabber(club_id)
|
||||
rows = (
|
||||
Order.query.filter(base)
|
||||
.exclude(ProductTypeID__isnull=True)
|
||||
.values('ProductTypeID')
|
||||
.annotate(cnt=Count('OrderID'))
|
||||
)
|
||||
out = {}
|
||||
for r in rows:
|
||||
lid = r.get('ProductTypeID')
|
||||
if lid is None:
|
||||
continue
|
||||
out[str(int(lid))] = int(r.get('cnt') or 0)
|
||||
return out
|
||||
except Exception as e:
|
||||
logger.warning('grab_pool_type_pending_counts failed club=%s: %s', club_id, e)
|
||||
return {}
|
||||
|
||||
|
||||
def team_pending_count(club_id: str) -> int:
|
||||
"""
|
||||
与 /zudui/dating 同口径:本俱乐部招募中,且关联订单进行中(Status=2)。
|
||||
"""
|
||||
club_id = (club_id or '').strip()
|
||||
if not club_id:
|
||||
return 0
|
||||
try:
|
||||
from orders.models import Order, TeamRecruit
|
||||
|
||||
qs = TeamRecruit.query.filter(
|
||||
club_id=club_id,
|
||||
status=TeamRecruit.STATUS_RECRUITING,
|
||||
)
|
||||
oids = list(qs.values_list('order_id', flat=True)[:2000])
|
||||
if not oids:
|
||||
return 0
|
||||
valid = set(
|
||||
Order.query.filter(
|
||||
OrderID__in=oids,
|
||||
ClubID=club_id,
|
||||
Status=2,
|
||||
).values_list('OrderID', flat=True)
|
||||
)
|
||||
return sum(1 for oid in oids if oid in valid)
|
||||
except Exception as e:
|
||||
logger.warning('team_pending_count failed club=%s: %s', club_id, e)
|
||||
return 0
|
||||
|
||||
|
||||
def dashou_badge_fields(club_id: str) -> dict:
|
||||
"""附加到接口 data 的角标字段(旧字段不受影响)。"""
|
||||
type_counts = grab_pool_type_pending_counts(club_id)
|
||||
total = int(sum(type_counts.values()))
|
||||
return {
|
||||
'type_pending_counts': type_counts,
|
||||
'pool_pending_total': total,
|
||||
'team_pending_count': int(team_pending_count(club_id)),
|
||||
}
|
||||
|
||||
|
||||
def attach_pending_to_leixing_list(leixing_list: list, type_counts: dict | None) -> list:
|
||||
"""给类型 list 每项附加 pending_count,不改动其它字段。"""
|
||||
counts = type_counts or {}
|
||||
out = []
|
||||
for item in leixing_list or []:
|
||||
if not isinstance(item, dict):
|
||||
out.append(item)
|
||||
continue
|
||||
row = dict(item)
|
||||
lid = row.get('id')
|
||||
key = str(int(lid)) if lid is not None else ''
|
||||
row['pending_count'] = int(counts.get(key) or 0)
|
||||
out.append(row)
|
||||
return out
|
||||
@@ -233,5 +233,8 @@ def build_fake_order_pool_response(request):
|
||||
'current_page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': (total + page_size - 1) // page_size if page_size else 0,
|
||||
'type_pending_counts': {},
|
||||
'pool_pending_total': 0,
|
||||
'team_pending_count': 0,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -382,6 +382,13 @@ class DashouDingdanHuoquView(APIView):
|
||||
|
||||
has_more = (page * page_size) < total
|
||||
|
||||
badge = {}
|
||||
try:
|
||||
from orders.services.dashou_badges import dashou_badge_fields
|
||||
badge = dashou_badge_fields(club_id)
|
||||
except Exception as e:
|
||||
logger.warning('ddhq 角标附加失败: %s', e)
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'msg': '获取成功',
|
||||
@@ -393,6 +400,7 @@ class DashouDingdanHuoquView(APIView):
|
||||
'page_size': page_size,
|
||||
'total_pages': (total + page_size - 1) // page_size,
|
||||
'clumber': user_clumber,
|
||||
**badge,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -762,13 +770,24 @@ class DashouDingdanHuoquView1(APIView):
|
||||
if total_count == 0:
|
||||
has_more = False
|
||||
|
||||
badge = {}
|
||||
try:
|
||||
from jituan.services.club_context import resolve_effective_club_id
|
||||
from orders.services.dashou_badges import dashou_badge_fields
|
||||
badge = dashou_badge_fields(
|
||||
resolve_effective_club_id(request, getattr(request, 'user', None))
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning('dshqdingdan 角标附加失败: %s', e)
|
||||
|
||||
return Response({
|
||||
'code': 0,
|
||||
'msg': '成功',
|
||||
'data': {
|
||||
'list': order_list,
|
||||
'has_more': has_more,
|
||||
'total': total_count
|
||||
'total': total_count,
|
||||
**badge,
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@@ -1568,15 +1587,26 @@ class DashouHuoquLeixingView(APIView):
|
||||
club_id = resolve_effective_club_id(request, request.user)
|
||||
leixing_list = build_club_leixing_list_for_api(club_id)
|
||||
|
||||
badge = {}
|
||||
try:
|
||||
from orders.services.dashou_badges import dashou_badge_fields, attach_pending_to_leixing_list
|
||||
badge = dashou_badge_fields(club_id)
|
||||
leixing_list = attach_pending_to_leixing_list(
|
||||
leixing_list, badge.get('type_pending_counts'),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning('dsqdhqddlx 角标附加失败: %s', e)
|
||||
|
||||
logger.info(f"返回商品类型数据:{len(leixing_list)}条,俱乐部:{club_id} 用户: {request.user.UserUID}")
|
||||
|
||||
# 🔴 返回成功响应
|
||||
# 注意:保持与前端原数据格式完全一致
|
||||
# 注意:保持与前端原数据格式完全一致;角标为新增字段,不影响旧客户端
|
||||
return Response({
|
||||
"code": 200,
|
||||
"msg": "成功",
|
||||
"data": {
|
||||
"list": leixing_list # 🔴 保持原字段名 "list"
|
||||
"list": leixing_list, # 🔴 保持原字段名 "list"
|
||||
**badge,
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@@ -207,6 +207,12 @@ class ZuduiDatingView(APIView):
|
||||
team_svc.serialize_recruit_public(r, orders.get(r.order_id), include_game_ids=False)
|
||||
for r in rows
|
||||
]
|
||||
badge = {}
|
||||
try:
|
||||
from orders.services.dashou_badges import dashou_badge_fields
|
||||
badge = dashou_badge_fields(club)
|
||||
except Exception:
|
||||
badge = {}
|
||||
return Response({
|
||||
'code': 0,
|
||||
'msg': 'ok',
|
||||
@@ -216,6 +222,7 @@ class ZuduiDatingView(APIView):
|
||||
'page': page,
|
||||
'page_size': page_size,
|
||||
'has_more': start + len(rows) < total,
|
||||
**badge,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -459,6 +459,15 @@ class DashouXinxiAPIView(APIView):
|
||||
'zuijinTixian': str(dashou_profile.jinritixian_jine) if dashou_profile.jinritixian_jine is not None else '0.00', # 最近提现金额(今日已提现)
|
||||
})
|
||||
|
||||
# 角标附加字段(不影响旧客户端)
|
||||
try:
|
||||
from jituan.services.club_context import resolve_effective_club_id
|
||||
from orders.services.dashou_badges import dashou_badge_fields
|
||||
cid = resolve_effective_club_id(request, request.user)
|
||||
data.update(dashou_badge_fields(cid))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 6. 返回成功响应
|
||||
return Response({
|
||||
'code': 200,
|
||||
|
||||
Reference in New Issue
Block a user