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,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user