From c865b51cdb8aa63173a6d3fb8621e9eadac8d1f6 Mon Sep 17 00:00:00 2001 From: XingQue Date: Tue, 21 Jul 2026 22:12:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=82=B9=E5=8D=95=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E5=BC=8F=E5=95=86=E5=93=81=E7=B1=BB=E5=9E=8B(shenhezh?= =?UTF-8?q?uangtai=3D4)=EF=BC=9A=E6=89=AB=E7=AE=A1=E4=BA=8B=E7=A0=81?= =?UTF-8?q?=E5=90=8E=E7=82=B9=E5=8D=95=E5=8F=AF=E8=A7=81=EF=BC=8C=E6=8A=A2?= =?UTF-8?q?=E5=8D=95=E6=B1=A0=E5=B1=95=E7=A4=BA3+4=EF=BC=8C=E5=95=86?= =?UTF-8?q?=E5=AE=B6=E7=AB=AF=E4=BB=8D=E4=BB=853=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- dingdan/views.py | 2 +- houtai/view.py | 16 +++++++------- shangpin/models.py | 18 +++++++++++++--- shangpin/views.py | 17 +++++++++++++-- utils/dashou_register_service.py | 15 ++++++++++++- .../migrations/0027_usermain_guanshi_saoma.py | 21 +++++++++++++++++++ yonghu/models.py | 8 +++++++ yonghu/views.py | 8 +++++++ 8 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 yonghu/migrations/0027_usermain_guanshi_saoma.py diff --git a/dingdan/views.py b/dingdan/views.py index 06b3670..7feb2e4 100644 --- a/dingdan/views.py +++ b/dingdan/views.py @@ -7731,7 +7731,7 @@ class DashouHuoquLeixingView(APIView): # 条件:shenhezhuangtai=1(正常状态) # 排序:先按 paixu 降序(数值大的在前),再按 id 升序 leixing_queryset = ShangpinLeixing.objects.filter( - shenhezhuangtai__in=[3] # 查询状态为1或9的记录 + shenhezhuangtai__in=[3, 4] # 商家端 + 点单隐藏式(抢单池可见) ).order_by('-paixu', 'id') '''leixing_queryset = ShangpinLeixing.objects.filter( shenhezhuangtai__in= [1,9] # 🔴 只取正常状态,排除审核专用 diff --git a/houtai/view.py b/houtai/view.py index 3981552..598e802 100644 --- a/houtai/view.py +++ b/houtai/view.py @@ -7722,10 +7722,10 @@ class ModifyProductTypeZoneView(APIView): try: shenhezhuangtai = int(request.data.get('shenhezhuangtai', 1)) - if shenhezhuangtai not in [1, 2,3]: + if shenhezhuangtai not in [1, 2, 3, 4]: raise ValueError except (TypeError, ValueError): - return Response({'code': 400, 'msg': '审核状态无效(必须为1或2)'}) + return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'}) is_cross_enabled = request.data.get('is_cross_enabled', False) is_cross_enabled = is_cross_enabled in [True, 'true', '1', 'on'] @@ -7834,12 +7834,12 @@ class ModifyProductTypeZoneView(APIView): if shenhezhuangtai is not None: try: new_val = int(shenhezhuangtai) - if new_val not in [1, 2,3]: + if new_val not in [1, 2, 3, 4]: raise ValueError if new_val != leixing.shenhezhuangtai: changes['shenhezhuangtai'] = new_val except (TypeError, ValueError): - return Response({'code': 400, 'msg': '审核状态无效(必须为1或2)'}) + return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'}) # 跨平台互通 is_cross = request.data.get('is_cross_enabled') @@ -7968,10 +7968,10 @@ class ModifyProductTypeZoneView(APIView): try: shenhezhuangtai = int(request.data.get('shenhezhuangtai', 1)) - if shenhezhuangtai not in [1, 2,3]: + if shenhezhuangtai not in [1, 2, 3, 4]: raise ValueError except (TypeError, ValueError): - return Response({'code': 400, 'msg': '审核状态无效(必须为1或2)'}) + return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'}) try: with transaction.atomic(): @@ -8015,12 +8015,12 @@ class ModifyProductTypeZoneView(APIView): if shenhezhuangtai is not None: try: new_val = int(shenhezhuangtai) - if new_val not in [1, 2,3]: + if new_val not in [1, 2, 3, 4]: raise ValueError if new_val != zhuanqu.shenhezhuangtai: changes['shenhezhuangtai'] = new_val except (TypeError, ValueError): - return Response({'code': 400, 'msg': '审核状态无效(必须为1或2)'}) + return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'}) if not changes: return Response({'code': 400, 'msg': '未做任何修改'}) diff --git a/shangpin/models.py b/shangpin/models.py index d9a692a..df1f8a8 100644 --- a/shangpin/models.py +++ b/shangpin/models.py @@ -35,7 +35,11 @@ class Shangpin(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间') paixu = models.IntegerField(default=0, verbose_name='排序权重') - shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') + shenhezhuangtai = models.IntegerField( + default=1, + verbose_name='审核状态', + help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式', + ) class Meta: db_table = 'shangpin' @@ -61,7 +65,11 @@ class ShangpinLeixing(models.Model): # 🔴 新增:是否特殊商品类型 is_special_type = models.BooleanField(default=False, verbose_name='是否特殊商品类型') paixu = models.IntegerField(default=0, verbose_name='排序权重') - shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') + shenhezhuangtai = models.IntegerField( + default=1, + verbose_name='审核状态', + help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式', + ) bankuai = models.ForeignKey( 'dengji.Bankuai', on_delete=models.SET_NULL, @@ -85,7 +93,11 @@ class ShangpinZhuanqu(models.Model): mingzi = models.CharField(max_length=45, null=True, blank=True, verbose_name='专区名称') # 15汉字 leixing_id = models.PositiveIntegerField(verbose_name='类型ID') # 直接存数字,不关联 paixu = models.IntegerField(default=0, verbose_name='排序权重') - shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') + shenhezhuangtai = models.IntegerField( + default=1, + verbose_name='审核状态', + help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式', + ) class Meta: db_table = 'shangpin_zhuanqu' diff --git a/shangpin/views.py b/shangpin/views.py index 8a2deeb..cf59c77 100644 --- a/shangpin/views.py +++ b/shangpin/views.py @@ -8,6 +8,7 @@ from shangpin.models import ShangpinLeixing, ShangpinZhuanqu, Shangpin from utils.xcx_sys_config import get_shangpin_shenhe_zhuangtai import logging from rest_framework.permissions import AllowAny # 新增这行 +from rest_framework_simplejwt.authentication import JWTAuthentication # 配置日志 logger = logging.getLogger(__name__) @@ -18,10 +19,15 @@ class ShangpinHuoquView(APIView): """ 商品数据获取接口 一次性返回商品类型、商品专区、商品列表 + + 筛选规则: + - 已登录且扫过管事二维码(guanshi_saoma=1):只返回 shenhezhuangtai=4(隐藏式) + - 其它:按全局审核开关返回 1 或 2(原逻辑不变) """ - # 应用节流(限制频率) + # 应用节流(限制频率);可选 JWT,未带 token 仍可访问 throttle_classes = [AnonRateThrottle] + authentication_classes = [JWTAuthentication] permission_classes = [AllowAny] def post(self, request): @@ -31,7 +37,14 @@ class ShangpinHuoquView(APIView): try: logger.info("收到商品数据获取请求") - shenhe_filter = get_shangpin_shenhe_zhuangtai() + 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) leixing_queryset = ShangpinLeixing.objects.filter( diff --git a/utils/dashou_register_service.py b/utils/dashou_register_service.py index 76f3d4e..e47b706 100644 --- a/utils/dashou_register_service.py +++ b/utils/dashou_register_service.py @@ -6,7 +6,7 @@ import logging from django.conf import settings from django.db import transaction -from yonghu.models import UserDashou, UserGuanshi +from yonghu.models import UserDashou, UserGuanshi, UserMain logger = logging.getLogger('yonghu.dashouzhuce') @@ -15,6 +15,19 @@ def get_default_dashou_invite_code(): return getattr(settings, 'DASHOU_DEFAULT_INVITE_CODE', '').strip() +def mark_guanshi_qr_scanned(user_main, invite_code_raw): + """ + 仅当请求明确带了管事邀请码(真实扫码)时,标记用户已扫过管事二维码。 + 空邀请码走默认码注册的不标记,避免误开隐藏商品。 + """ + if not user_main or not (invite_code_raw or '').strip(): + return + if getattr(user_main, 'guanshi_saoma', 0) == 1: + return + UserMain.objects.filter(pk=user_main.pk).update(guanshi_saoma=1) + user_main.guanshi_saoma = 1 + + def resolve_guanshi_for_dashou_register(invite_code): """ 根据邀请码查找管事;无邀请码时使用默认码;默认码查不到时按平台管事 yonghuid 回退。 diff --git a/yonghu/migrations/0027_usermain_guanshi_saoma.py b/yonghu/migrations/0027_usermain_guanshi_saoma.py new file mode 100644 index 0000000..448381f --- /dev/null +++ b/yonghu/migrations/0027_usermain_guanshi_saoma.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('yonghu', '0026_xiugaijilu_zuzhang_and_indexes'), + ] + + operations = [ + migrations.AddField( + model_name='usermain', + name='guanshi_saoma', + field=models.PositiveSmallIntegerField( + db_index=True, + default=0, + help_text='0=未扫 1=已扫', + verbose_name='是否扫过管事二维码', + ), + ), + ] diff --git a/yonghu/models.py b/yonghu/models.py index 02da517..de0ecaa 100644 --- a/yonghu/models.py +++ b/yonghu/models.py @@ -47,6 +47,14 @@ class UserMain(AbstractBaseUser): create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') + # 是否扫过管事二维码:0未扫 1已扫;扫过后点单端展示隐藏式商品(shenhezhuangtai=4) + guanshi_saoma = models.PositiveSmallIntegerField( + default=0, + db_index=True, + verbose_name='是否扫过管事二维码', + help_text='0=未扫 1=已扫', + ) + # 邀请码字段 #yaoqingma = models.CharField(max_length=20, blank=True, null=True, verbose_name='邀请码') diff --git a/yonghu/views.py b/yonghu/views.py index c7602b0..862047e 100644 --- a/yonghu/views.py +++ b/yonghu/views.py @@ -1376,6 +1376,7 @@ class DashouZhuceView(APIView): try: from utils.dashou_register_service import ( create_dashou_for_user, + mark_guanshi_qr_scanned, resolve_guanshi_for_dashou_register, ) @@ -1389,6 +1390,9 @@ class DashouZhuceView(APIView): 'data': None }, status=status.HTTP_404_NOT_FOUND) + # 真实扫码(带了邀请码)才标记,空码走默认不标记 + mark_guanshi_qr_scanned(current_user, yaoqingma) + # 2. 检查用户是否已是打手 (使用反向查询,性能最优) try: dashou_profile = current_user.dashou_profile @@ -6650,6 +6654,7 @@ class WechatLoginAndDashouRegisterView(APIView): from utils.dashou_register_service import ( create_dashou_for_user, ensure_guanshi_profile_for_user, + mark_guanshi_qr_scanned, resolve_guanshi_for_dashou_register, ) @@ -6696,6 +6701,9 @@ class WechatLoginAndDashouRegisterView(APIView): # 新用户:创建老板扩展表 UserBoss.objects.create(user=user_main, nickname='微信用户') + # 真实扫码(带了邀请码)才标记 + mark_guanshi_qr_scanned(user_main, yaoqingma) + # 验证管事状态 if guanshi_profile.zhuangtai != 1: return self.fanhuiZhihouDengluXinxi(user_main, guanshi_jinyong=True)