fix: 打手有效会员改用 Exists,修复 values 字典导致 __in 永假

This commit is contained in:
XingQue
2026-07-29 22:39:30 +08:00
parent ae8a2bb993
commit 531639731a

View File

@@ -76,7 +76,8 @@ from backend.models import WithdrawalDailyStats
## users
from users.models import (
UserGuanshi, UserBoss, UserZuzhang,
UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan
UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan,
DashouZengsongHuiyuan,
)
from users.business_models import User
from jituan.constants import CLUB_ID_DEFAULT
@@ -203,15 +204,38 @@ class KefuGetDashouListView(APIView):
dashou_qs = dashou_qs.filter(zhuangtai=zhuangtai_val)
now = timezone.now()
# 有效会员:与打手详情一致——只认到期时间未过(daoqi_time >= now
# 不要按 Huiyuangoumai.club_id 过滤:历史上大量记录默认 xq会把本店打手会员全滤成「无」
# 俱乐部范围已由 dashou_qsuser.ClubID保证会员按 yonghu_id 归属即可。
# 也不强依赖 huiyuan_zhuangtai过期态可能未及时回写详情用 jiance_shifou_daoqi 以时间为准
active_hy_base = Huiyuangoumai.query.filter(daoqi_time__gte=now)
active_hy_for_filter = active_hy_base
# 有效会员:与打手详情 / clumber 一致——daoqi_time > now(未过期)。
# 含购买表 Huiyuangoumai + 赠送表 DashouZengsongHuiyuan
# 必须用 Exists(OuterRef),禁止 FluentQuery.values() 丢进 __in
# values() 返回的是字典迭代器UserUID__in=[{'yonghu_id':...}] 永远匹配不到
bought_any = Huiyuangoumai.objects.filter(
yonghu_id=OuterRef('user__UserUID'),
daoqi_time__gt=now,
)
gift_any = DashouZengsongHuiyuan.objects.filter(
yonghu_id=OuterRef('user__UserUID'),
daoqi_time__gt=now,
)
dashou_qs = dashou_qs.annotate(
_any_hy=Exists(bought_any),
_any_gift=Exists(gift_any),
)
if huiyuan_id:
active_hy_for_filter = active_hy_for_filter.filter(huiyuan_id=huiyuan_id)
active_member_uids = active_hy_for_filter.values('yonghu_id').distinct()
bought_type = Huiyuangoumai.objects.filter(
yonghu_id=OuterRef('user__UserUID'),
daoqi_time__gt=now,
huiyuan_id=huiyuan_id,
)
gift_type = DashouZengsongHuiyuan.objects.filter(
yonghu_id=OuterRef('user__UserUID'),
daoqi_time__gt=now,
huiyuan_id=huiyuan_id,
)
dashou_qs = dashou_qs.annotate(
_type_hy=Exists(bought_type),
_type_gift=Exists(gift_type),
)
has_member_raw = request.data.get('has_member', None)
if has_member_raw is not None and has_member_raw != '':
@@ -220,14 +244,16 @@ class KefuGetDashouListView(APIView):
except (TypeError, ValueError):
return Response({'code': 400, 'msg': '会员筛选格式错误'})
if has_member_val == 1:
dashou_qs = dashou_qs.filter(user__UserUID__in=active_member_uids)
if huiyuan_id:
dashou_qs = dashou_qs.filter(Q(_type_hy=True) | Q(_type_gift=True))
else:
dashou_qs = dashou_qs.filter(Q(_any_hy=True) | Q(_any_gift=True))
elif has_member_val == 0:
any_member_uids = active_hy_base.values('yonghu_id').distinct()
dashou_qs = dashou_qs.exclude(user__UserUID__in=any_member_uids)
dashou_qs = dashou_qs.filter(_any_hy=False, _any_gift=False)
else:
return Response({'code': 400, 'msg': '会员筛选值无效'})
elif huiyuan_id:
dashou_qs = dashou_qs.filter(user__UserUID__in=active_member_uids)
dashou_qs = dashou_qs.filter(Q(_type_hy=True) | Q(_type_gift=True))
# 押金≥阈值人数:在应用押金比较筛之前统计(相对其它已选条件)
yajin_gte_count = None
@@ -246,15 +272,12 @@ class KefuGetDashouListView(APIView):
else:
dashou_qs = dashou_qs.filter(yajin=yajin_value)
filtered_uids_subq = dashou_qs.values('user__UserUID')
total_dashou = dashou_qs.count()
_status_agg = dashou_qs.aggregate(
normal_count=Count('id', filter=Q(zhanghaozhuangtai=1)),
banned_count=Count('id', filter=Q(zhanghaozhuangtai=0)),
)
valid_dashou_count = active_hy_base.filter(
yonghu_id__in=filtered_uids_subq,
).values('yonghu_id').distinct().count()
valid_dashou_count = dashou_qs.filter(Q(_any_hy=True) | Q(_any_gift=True)).count()
no_member_count = max(total_dashou - valid_dashou_count, 0)
offset = (page - 1) * page_size
@@ -263,21 +286,48 @@ class KefuGetDashouListView(APIView):
hy_by_uid = {}
if page_uids:
page_hy = active_hy_base.filter(yonghu_id__in=page_uids).values(
'yonghu_id', 'huiyuan_id', 'jieshao',
)
name_ids = set()
bought_rows = list(Huiyuangoumai.objects.filter(
yonghu_id__in=page_uids,
daoqi_time__gt=now,
).values('yonghu_id', 'huiyuan_id', 'jieshao'))
gift_rows = list(DashouZengsongHuiyuan.objects.filter(
yonghu_id__in=page_uids,
daoqi_time__gt=now,
).values('yonghu_id', 'huiyuan_id'))
for row in bought_rows:
name_ids.add(row['huiyuan_id'])
for row in gift_rows:
name_ids.add(row['huiyuan_id'])
name_map = {
h['huiyuan_id']: (h['jieshao'] or '')
for h in Huiyuan.query.filter(
huiyuan_id__in={r['huiyuan_id'] for r in page_hy}
).values('huiyuan_id', 'jieshao')
for h in Huiyuan.objects.filter(huiyuan_id__in=name_ids).values('huiyuan_id', 'jieshao')
}
for row in page_hy:
seen_pair = set()
for row in bought_rows:
uid = row['yonghu_id']
name = (row.get('jieshao') or '').strip() or name_map.get(row['huiyuan_id'], '')
hid = row['huiyuan_id']
key = (uid, hid)
if key in seen_pair:
continue
seen_pair.add(key)
name = (row.get('jieshao') or '').strip() or name_map.get(hid, '') or hid
hy_by_uid.setdefault(uid, []).append({
'huiyuan_id': row['huiyuan_id'],
'name': name or row['huiyuan_id'],
'huiyuan_id': hid,
'name': name,
})
for row in gift_rows:
uid = row['yonghu_id']
hid = row['huiyuan_id']
key = (uid, hid)
if key in seen_pair:
continue
seen_pair.add(key)
name = name_map.get(hid, '') or hid
hy_by_uid.setdefault(uid, []).append({
'huiyuan_id': hid,
'name': name,
'is_gift': True,
})
result = []