fix: 假单开启后无对应会员稳定走假池,避免真假交替

This commit is contained in:
XingQue
2026-07-30 20:03:42 +08:00
parent bb74140150
commit c8a3d0274d
3 changed files with 74 additions and 25 deletions

View File

@@ -1,4 +1,5 @@
"""抢单大厅假单:按俱乐部开关 + 按商品类型会员资格展示假数据。"""
import logging
import random
from datetime import datetime, timedelta
@@ -14,58 +15,99 @@ from jituan.services.fake_grab_switch import is_club_fake_grab_enabled
from jituan.services.huiyuan_bundle import normalize_huiyuan_id, user_has_huiyuan_access
from orders.models import FakeGrabOrder, FakeGrabOrderShuffleState
logger = logging.getLogger(__name__)
DEFAULT_DISPATCHER_AVATAR = 'beijing/morentouxiang.jpg'
SHUFFLE_STATE_PK = 1
def _leixing_required_huiyuan_id(leixing_id):
"""商品类型绑定的会员 ID无绑定则视为不要求会员。"""
def _leixing_membership_meta(leixing_id):
"""
返回 (required_huiyuan_id, yaoqiuleixing)。
required 为空表示类型未绑定会员 ID。
"""
if leixing_id is None:
return ''
return '', None
try:
from products.models import ShangpinLeixing
row = ShangpinLeixing.query.filter(id=int(leixing_id)).values('huiyuan_id').first()
row = ShangpinLeixing.query.filter(id=int(leixing_id)).values(
'huiyuan_id', 'yaoqiuleixing',
).first()
if not row:
return ''
return normalize_huiyuan_id(row.get('huiyuan_id'))
return '', None
return (
normalize_huiyuan_id(row.get('huiyuan_id')),
row.get('yaoqiuleixing'),
)
except Exception:
return ''
logger.exception('read ShangpinLeixing membership meta failed leixing_id=%s', leixing_id)
return '', None
def dashou_should_use_fake_pool(user, club_id=None, leixing_id=None):
"""
当前 Tab商品类型是否只展示假单
- 俱乐部未开启假单功能 → 否(看真实单)
- 账号封禁
- 该类型要求的会员:已充(含总会员覆盖子类型)→ 否
- 未充对应会员
不同类型互不影响;假单在独立表,抢不了。
当前商品类型 Tab 是否只展示假单(结果必须稳定,同用户同类型每次请求一致)
- 俱乐部未开启真单
- 已开启后:
- 账号异常/封禁假单
- 类型绑定了会员 ID有对应会员含总会员覆盖子类型且未过期 → 真单;否则 → 假单
- 类型要求会员但未绑定 ID → 假单(无法核验资格时不开真池)
- 类型不要求会员 → 真单
不同类型互不影响。查库异常时 fail-closed偏向假单避免闪回真单。
"""
cid = (club_id or '').strip()
if not cid or not is_club_fake_grab_enabled(cid):
if not cid:
return False
try:
enabled = is_club_fake_grab_enabled(cid)
except Exception:
logger.exception('is_club_fake_grab_enabled failed club=%s', cid)
return False
if not enabled:
return False
# ---------- 俱乐部假单已开启:默认假单,只有核验通过才出真单 ----------
try:
dashou = user.DashouProfile
except ObjectDoesNotExist:
return True
except Exception:
logger.exception('read DashouProfile failed uid=%s', getattr(user, 'UserUID', ''))
return True
if dashou.zhanghaozhuangtai != 1:
if int(getattr(dashou, 'zhanghaozhuangtai', 0) or 0) != 1:
return True
if leixing_id is None:
# 未指定类型时不整池切假单,走真实单列表
return False
# 未类型时无法判断「对应会员」,开启假单后不出真池
return True
required = _leixing_required_huiyuan_id(leixing_id)
if not required:
# 类型未绑会员 → 不推假单
return False
required, yaoqiu = _leixing_membership_meta(leixing_id)
if user_has_huiyuan_access(user.UserUID, required, club_id=cid):
return False
if required:
try:
if user_has_huiyuan_access(user.UserUID, required, club_id=cid):
return False # 有对应会员(或总会员含该子类型)→ 真单
except Exception:
logger.exception(
'user_has_huiyuan_access failed uid=%s required=%s club=%s',
getattr(user, 'UserUID', ''), required, cid,
)
return True # 异常 → 假单,避免闪真单
return True # 无会员 / 已过期 → 假单
return True
# 未绑定会员 ID
try:
yaoqiu_int = int(yaoqiu) if yaoqiu is not None else 0
except (TypeError, ValueError):
yaoqiu_int = 0
if yaoqiu_int == 1:
# 要求会员却没配 ID不能放行真单
return True
# 不要求会员(押金单等)→ 真单
return False
def _scope_key(club_id, leixing_id):
@@ -262,5 +304,6 @@ def build_fake_order_pool_response(request):
'type_pending_counts': {},
'pool_pending_total': 0,
'team_pending_count': 0,
'is_fake_pool': True,
},
})

View File

@@ -401,6 +401,7 @@ class DashouDingdanHuoquView(APIView):
'page_size': page_size,
'total_pages': (total + page_size - 1) // page_size,
'clumber': user_clumber,
'is_fake_pool': False,
**badge,
}
})