Files
Django/orders/services/dashou_badges.py

154 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""打手端角标计数:抢单池按类型待接单数、组队大厅待加入数。
仅供响应附加字段,不改变原有业务筛选逻辑。
"""
from __future__ import annotations
import logging
from django.db.models import Count
logger = logging.getLogger(__name__)
def _fake_type_counts(club_id: str) -> dict[str, int]:
try:
from orders.models import FakeGrabOrder
rows = (
FakeGrabOrder.query.filter(ClubID=club_id)
.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('_fake_type_counts failed club=%s: %s', club_id, e)
return {}
def grab_pool_type_pending_counts(club_id: str, user=None) -> dict[str, int]:
"""
与 /dingdan/ddhq 同口径Status in (1,7) + 抢单俱乐部范围,按 ProductTypeID 聚合。
若传入 user按假单展示模式把假单数计入mix/fake_only 计入real_only/off 不计)。
返回 { \"类型id\": 数量 }key 一律 str。
"""
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)
if user is not None:
try:
from orders.services.fake_order_pool import (
MODE_FAKE_ONLY,
MODE_MIX,
resolve_fake_pool_mode,
)
fake_counts = _fake_type_counts(club_id)
# 所有出现过的类型(真单或假单)
all_keys = set(out.keys()) | set(fake_counts.keys())
adjusted = {}
for key in all_keys:
try:
lid = int(key)
except (TypeError, ValueError):
continue
real_n = int(out.get(key) or 0)
fake_n = int(fake_counts.get(key) or 0)
mode = resolve_fake_pool_mode(user, club_id=club_id, leixing_id=lid)
if mode == MODE_FAKE_ONLY:
adjusted[key] = fake_n
elif mode == MODE_MIX:
adjusted[key] = real_n + fake_n
else:
# off / real_only不计假单
adjusted[key] = real_n
out = adjusted
except Exception as e:
logger.warning('merge fake into type counts failed: %s', e)
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, user=None) -> dict:
"""附加到接口 data 的角标字段(旧字段不受影响)。"""
type_counts = grab_pool_type_pending_counts(club_id, user=user)
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