From 2287117397c4a90feaf20a778f59f5791238e213 Mon Sep 17 00:00:00 2001 From: XingQue Date: Tue, 21 Jul 2026 22:30:50 +0800 Subject: [PATCH] =?UTF-8?q?=E7=82=B9=E5=8D=95=E8=8E=B7=E5=8F=96=E5=95=86?= =?UTF-8?q?=E5=93=81=E5=85=88=E6=9F=A5=20guanshi=5Fsaoma=EF=BC=8C=E6=89=AB?= =?UTF-8?q?=E8=BF=87=E5=88=99=E5=BC=BA=E5=88=B6=E5=8F=AA=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E5=BC=8F4=EF=BC=9B=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E5=BC=BA=E5=88=B6=E8=90=BD=E5=BA=93=E5=B9=B6?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- shangpin/views.py | 38 ++++++++++++++++++++++---------- utils/dashou_register_service.py | 31 ++++++++++++++++---------- utils/jwt_auth.py | 13 +++++++++++ 3 files changed, 58 insertions(+), 24 deletions(-) diff --git a/shangpin/views.py b/shangpin/views.py index cf59c77..89969f9 100644 --- a/shangpin/views.py +++ b/shangpin/views.py @@ -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, diff --git a/utils/dashou_register_service.py b/utils/dashou_register_service.py index e05bcaa..82a201f 100644 --- a/utils/dashou_register_service.py +++ b/utils/dashou_register_service.py @@ -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): diff --git a/utils/jwt_auth.py b/utils/jwt_auth.py index 89e12d1..9aec75c 100644 --- a/utils/jwt_auth.py +++ b/utils/jwt_auth.py @@ -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