101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""打手端角标计数:抢单池按类型待接单数、组队大厅待加入数。
|
||
|
||
仅供响应附加字段,不改变原有业务筛选逻辑。
|
||
"""
|
||
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
|