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