点单获取商品先查 guanshi_saoma,扫过则强制只返回隐藏式4;扫码标记强制落库并校验。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-21 22:30:50 +08:00
parent 364c3f1d24
commit 2287117397
3 changed files with 58 additions and 24 deletions

View File

@@ -6,9 +6,10 @@ from rest_framework.throttling import AnonRateThrottle
from django.db import models
from shangpin.models import ShangpinLeixing, ShangpinZhuanqu, Shangpin
from utils.xcx_sys_config import get_shangpin_shenhe_zhuangtai
from utils.jwt_auth import OptionalYonghuidJWTAuthentication
from yonghu.models import UserMain
import logging
from rest_framework.permissions import AllowAny # 新增这行
from rest_framework_simplejwt.authentication import JWTAuthentication
# 配置日志
logger = logging.getLogger(__name__)
@@ -21,15 +22,36 @@ class ShangpinHuoquView(APIView):
一次性返回商品类型、商品专区、商品列表
筛选规则:
- 已登录且扫过管事二维码(guanshi_saoma=1):只返回 shenhezhuangtai=4隐藏式
- 已登录且扫过管事二维码(guanshi_saoma=1):只返回 shenhezhuangtai=4隐藏式
与后台「点单商品展示/体验」开关无关
- 其它:按全局审核开关返回 1 或 2原逻辑不变
"""
# 应用节流(限制频率);可选 JWT未带 token 仍可访问
throttle_classes = [AnonRateThrottle]
authentication_classes = [JWTAuthentication]
authentication_classes = [OptionalYonghuidJWTAuthentication]
permission_classes = [AllowAny]
def _resolve_shenhe_filter(self, request):
"""先查用户扫码标记;扫过则强制 4否则走全局体验开关。"""
user = request.user
if getattr(user, 'is_authenticated', False):
saoma = UserMain.objects.filter(pk=user.pk).values_list('guanshi_saoma', flat=True).first()
if saoma == 1:
logger.info(
'点单商品:用户已扫管事码,强制隐藏式 shenhezhuangtai=4 yonghuid=%s',
getattr(user, 'yonghuid', ''),
)
return 4
logger.info(
'点单商品:用户未扫管事码 guanshi_saoma=%s yonghuid=%s',
saoma,
getattr(user, 'yonghuid', ''),
)
shenhe = get_shangpin_shenhe_zhuangtai()
logger.info('点单商品:按体验开关 shenhezhuangtai=%s', shenhe)
return shenhe
def post(self, request):
"""
处理POST请求返回所有商品相关数据
@@ -37,15 +59,7 @@ class ShangpinHuoquView(APIView):
try:
logger.info("收到商品数据获取请求")
user = request.user
if (
getattr(user, 'is_authenticated', False)
and getattr(user, 'guanshi_saoma', 0) == 1
):
shenhe_filter = 4
else:
shenhe_filter = get_shangpin_shenhe_zhuangtai()
logger.info("点单商品展示模式 shenhezhuangtai=%s", shenhe_filter)
shenhe_filter = self._resolve_shenhe_filter(request)
leixing_queryset = ShangpinLeixing.objects.filter(
shenhezhuangtai=shenhe_filter,

View File

@@ -17,21 +17,28 @@ def get_default_dashou_invite_code():
def mark_guanshi_qr_scanned(user_main, invite_code_raw):
"""
仅当请求明确带了管事邀请码(真实扫码)时,标记用户已扫过管事二维码
空邀请码走默认码注册的不标记,避免误开隐藏商品
已是打手/老用户同样必须写入,注册流程可跳过,标记不可跳过
扫管事码接口调用:只要请求带了邀请码,就把 guanshi_saoma 置为 1
已是打手/老用户同样写入;注册可跳过,标记不可跳过
空邀请码(走默认码)不标记,避免误开隐藏商品
"""
if not user_main or not (invite_code_raw or '').strip():
return False
updated = UserMain.objects.filter(pk=user_main.pk).exclude(guanshi_saoma=1).update(guanshi_saoma=1)
user_main.guanshi_saoma = 1
if updated:
logger.info(
'扫管事码标记已写入 yonghuid=%s invite=%s',
getattr(user_main, 'yonghuid', ''),
(invite_code_raw or '')[:20],
logger.warning(
'扫管事码未标记invite为空或用户为空 yonghuid=%s',
getattr(user_main, 'yonghuid', None),
)
return True
return False
rows = UserMain.objects.filter(pk=user_main.pk).update(guanshi_saoma=1)
user_main.guanshi_saoma = 1
# 再读一次确认已写入
db_val = UserMain.objects.filter(pk=user_main.pk).values_list('guanshi_saoma', flat=True).first()
logger.info(
'扫管事码标记结果 yonghuid=%s rows=%s guanshi_saoma=%s invite=%s',
getattr(user_main, 'yonghuid', ''),
rows,
db_val,
(invite_code_raw or '')[:20],
)
return db_val == 1
def resolve_guanshi_for_dashou_register(invite_code):

View File

@@ -37,3 +37,16 @@ class YonghuidJWTAuthentication(JWTAuthentication):
if self.user_model.objects.filter(id=int(legacy_id)).exists():
return legacy_id, 'id'
return legacy_id, field
class OptionalYonghuidJWTAuthentication(YonghuidJWTAuthentication):
"""可选登录:有合法 token 则识别用户,无/坏 token 当匿名,不打断 AllowAny 接口。"""
def authenticate(self, request):
header = self.get_header(request)
if header is None:
return None
try:
return super().authenticate(request)
except (InvalidToken, AuthenticationFailed):
return None