feat: 抢单池/组队角标计数多接口附加字段(兼容旧客户端)

This commit is contained in:
XingQue
2026-07-27 17:19:41 +08:00
parent 9b9203587c
commit 17b38d07a9
5 changed files with 152 additions and 3 deletions

View 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

View File

@@ -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,
},
})