feat: 只看审核按俱乐部隔离,商品管理支持俱乐部视图
未绑店出货开关按 club_id 配置;后台商品列表可在具体小程序下管理并切换审核展示。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,7 +5,7 @@ from .view import (GetRolePermissionView,
|
|||||||
ModifyRolePermissionView, AddRoleView, GetAdminRolesView, GetAdminUserListView, AddAdminUserView,
|
ModifyRolePermissionView, AddRoleView, GetAdminRolesView, GetAdminUserListView, AddAdminUserView,
|
||||||
ModifyAdminUserView, KefuGetDashouListView, KefuGetDashouDetailView, KefuUpdateDashouView, KefuGetShangjiaListView,
|
ModifyAdminUserView, KefuGetDashouListView, KefuGetDashouDetailView, KefuUpdateDashouView, KefuGetShangjiaListView,
|
||||||
KefuGetShangjiaDetailView, KefuUpdateShangjiaView, GetProductBaseDataView, GetProductListView, SaveProductOrderView,
|
KefuGetShangjiaDetailView, KefuUpdateShangjiaView, GetProductBaseDataView, GetProductListView, SaveProductOrderView,
|
||||||
AddProductView, DeleteProductView, GetProductDetailView, UpdateProductView, UpdateMemberView, GetMemberListView,
|
AddProductView, DeleteProductView, GetProductDetailView, UpdateProductView, UpdateZhiKanShenheView, UpdateMemberView, GetMemberListView,
|
||||||
AddMemberView, GetGuanliListView, GetGuanliDetailView, PromoteGuanshiToZuzhangView, ChangeInviterView, UpdateGuanliView, GetWithdrawSettingsView,
|
AddMemberView, GetGuanliListView, GetGuanliDetailView, PromoteGuanshiToZuzhangView, ChangeInviterView, UpdateGuanliView, GetWithdrawSettingsView,
|
||||||
UpdateWithdrawSettingsView, GetZuzhangListView, GetZuzhangDetailView, UpdateZuzhangView, GetOperationLogListView, GetProductTypeZoneView,
|
UpdateWithdrawSettingsView, GetZuzhangListView, GetZuzhangDetailView, UpdateZuzhangView, GetOperationLogListView, GetProductTypeZoneView,
|
||||||
ModifyProductTypeZoneView, GetRateView, ModifyRateView, PopupNoticeListAPIView, PopupNoticeModifyAPIView,ShopListView,
|
ModifyProductTypeZoneView, GetRateView, ModifyRateView, PopupNoticeListAPIView, PopupNoticeModifyAPIView,ShopListView,
|
||||||
@@ -44,6 +44,7 @@ urlpatterns = [
|
|||||||
path('htscsp', DeleteProductView.as_view(), name='后台删除商品'),
|
path('htscsp', DeleteProductView.as_view(), name='后台删除商品'),
|
||||||
path('htsphqxq', GetProductDetailView.as_view(), name='后台获取商品详情'),
|
path('htsphqxq', GetProductDetailView.as_view(), name='后台获取商品详情'),
|
||||||
path('bcspxg', UpdateProductView.as_view(), name='后台更新商品数据'),
|
path('bcspxg', UpdateProductView.as_view(), name='后台更新商品数据'),
|
||||||
|
path('htxgzhikan', UpdateZhiKanShenheView.as_view(), name='后台更新只看审核开关'),
|
||||||
|
|
||||||
path('hthqhylb', GetMemberListView.as_view(), name='后台获取会员列表'),
|
path('hthqhylb', GetMemberListView.as_view(), name='后台获取会员列表'),
|
||||||
path('htxghyxx', UpdateMemberView.as_view(), name='后台更新会员信息'),
|
path('htxghyxx', UpdateMemberView.as_view(), name='后台更新会员信息'),
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ from .views.kefu import (
|
|||||||
from .views.products import (
|
from .views.products import (
|
||||||
GetProductBaseDataView, GetProductListView, SaveProductOrderView,
|
GetProductBaseDataView, GetProductListView, SaveProductOrderView,
|
||||||
AddProductView, DeleteProductView, GetProductDetailView, UpdateProductView,
|
AddProductView, DeleteProductView, GetProductDetailView, UpdateProductView,
|
||||||
|
UpdateZhiKanShenheView,
|
||||||
)
|
)
|
||||||
from .views.members import (
|
from .views.members import (
|
||||||
GetMemberListView, UpdateMemberView, AddMemberView,
|
GetMemberListView, UpdateMemberView, AddMemberView,
|
||||||
@@ -103,6 +104,7 @@ __all__ = [
|
|||||||
# products
|
# products
|
||||||
'GetProductBaseDataView', 'GetProductListView', 'SaveProductOrderView',
|
'GetProductBaseDataView', 'GetProductListView', 'SaveProductOrderView',
|
||||||
'AddProductView', 'DeleteProductView', 'GetProductDetailView', 'UpdateProductView',
|
'AddProductView', 'DeleteProductView', 'GetProductDetailView', 'UpdateProductView',
|
||||||
|
'UpdateZhiKanShenheView',
|
||||||
# members
|
# members
|
||||||
'GetMemberListView', 'UpdateMemberView', 'AddMemberView',
|
'GetMemberListView', 'UpdateMemberView', 'AddMemberView',
|
||||||
'ClubMemberCatalogView', 'ClubMemberEnableView', 'ClubMemberDisableView',
|
'ClubMemberCatalogView', 'ClubMemberEnableView', 'ClubMemberDisableView',
|
||||||
|
|||||||
@@ -142,14 +142,24 @@ class GetProductBaseDataView(APIView):
|
|||||||
if '2200a' not in permissions:
|
if '2200a' not in permissions:
|
||||||
return Response({'code': 403, 'msg': '无权限管理商品'})
|
return Response({'code': 403, 'msg': '无权限管理商品'})
|
||||||
|
|
||||||
# 获取所有商品类型(按 paixu 升序)
|
# 获取所有商品类型(按 paixu 升序);商品数按当前俱乐部统计
|
||||||
|
from jituan.services.club_context import filter_club_char_field, resolve_club_scope
|
||||||
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
|
from shop.services.shenhe_config import get_or_create_shenhe_config, is_zhi_kan_shenhe_enabled
|
||||||
|
|
||||||
type_qs = ShangpinLeixing.query.all().order_by('paixu')
|
type_qs = ShangpinLeixing.query.all().order_by('paixu')
|
||||||
# 批量聚合商品数量,避免循环内 N+1 count
|
# 批量聚合商品数量,避免循环内 N+1 count(按俱乐部)
|
||||||
|
_public_sp = filter_club_char_field(
|
||||||
|
Shangpin.query.filter(
|
||||||
|
dianpu__isnull=True, dianpu_leixing__isnull=True, leixing_id__isnull=False
|
||||||
|
),
|
||||||
|
request,
|
||||||
|
field='club_id',
|
||||||
|
)
|
||||||
_type_counts = {
|
_type_counts = {
|
||||||
item['leixing_id']: item['cnt']
|
item['leixing_id']: item['cnt']
|
||||||
for item in Shangpin.query.filter(
|
for item in _public_sp.values('leixing_id').annotate(cnt=Count('id'))
|
||||||
dianpu__isnull=True, dianpu_leixing__isnull=True, leixing_id__isnull=False
|
|
||||||
).values('leixing_id').annotate(cnt=Count('id'))
|
|
||||||
}
|
}
|
||||||
type_list = []
|
type_list = []
|
||||||
for t in type_qs:
|
for t in type_qs:
|
||||||
@@ -164,7 +174,6 @@ class GetProductBaseDataView(APIView):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# 获取专区(按俱乐部隔离;集团汇总看全部)
|
# 获取专区(按俱乐部隔离;集团汇总看全部)
|
||||||
from jituan.services.club_context import filter_club_char_field
|
|
||||||
zone_qs = filter_club_char_field(
|
zone_qs = filter_club_char_field(
|
||||||
ShangpinZhuanqu.query.all().order_by('paixu'), request, field='club_id'
|
ShangpinZhuanqu.query.all().order_by('paixu'), request, field='club_id'
|
||||||
)
|
)
|
||||||
@@ -194,12 +203,24 @@ class GetProductBaseDataView(APIView):
|
|||||||
# 获取所有会员(只需 ID、介绍、价格)
|
# 获取所有会员(只需 ID、介绍、价格)
|
||||||
member_list = list(Huiyuan.query.all().values('huiyuan_id', 'jieshao', 'jiage'))
|
member_list = list(Huiyuan.query.all().values('huiyuan_id', 'jieshao', 'jiage'))
|
||||||
|
|
||||||
|
# 本俱乐部「只看审核」开关(集团汇总不下发可写状态)
|
||||||
|
club_scoped = resolve_club_scope(request) != DATA_SCOPE_ALL
|
||||||
|
zhi_kan_shenhe = True
|
||||||
|
club_id = ''
|
||||||
|
if club_scoped:
|
||||||
|
club_id = resolve_club_id_for_write(request) or ''
|
||||||
|
get_or_create_shenhe_config(club_id)
|
||||||
|
zhi_kan_shenhe = is_zhi_kan_shenhe_enabled(club_id)
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
'code': 0,
|
'code': 0,
|
||||||
'data': {
|
'data': {
|
||||||
'type_list': type_list,
|
'type_list': type_list,
|
||||||
'zone_list': zone_list,
|
'zone_list': zone_list,
|
||||||
'member_list': member_list,
|
'member_list': member_list,
|
||||||
|
'zhi_kan_shenhe': zhi_kan_shenhe,
|
||||||
|
'club_scoped': club_scoped,
|
||||||
|
'club_id': club_id,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -701,6 +722,14 @@ class AddProductView(APIView):
|
|||||||
zhuanqu_obj = ShangpinZhuanqu.query.get(id=zhuanqu_id)
|
zhuanqu_obj = ShangpinZhuanqu.query.get(id=zhuanqu_id)
|
||||||
if zhuanqu_obj.leixing_id != leixing_id:
|
if zhuanqu_obj.leixing_id != leixing_id:
|
||||||
return Response({'code': 400, 'msg': '专区不属于该商品类型'})
|
return Response({'code': 400, 'msg': '专区不属于该商品类型'})
|
||||||
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_context import resolve_club_scope
|
||||||
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
|
if resolve_club_scope(request) != DATA_SCOPE_ALL:
|
||||||
|
write_club = resolve_club_id_for_write(request)
|
||||||
|
zone_club = getattr(zhuanqu_obj, 'club_id', None) or 'xq'
|
||||||
|
if zone_club != write_club:
|
||||||
|
return Response({'code': 400, 'msg': '专区不属于当前俱乐部,请先切换俱乐部或选择本俱乐部专区'})
|
||||||
except ShangpinZhuanqu.DoesNotExist:
|
except ShangpinZhuanqu.DoesNotExist:
|
||||||
return Response({'code': 400, 'msg': '商品专区不存在'})
|
return Response({'code': 400, 'msg': '商品专区不存在'})
|
||||||
|
|
||||||
@@ -1134,6 +1163,52 @@ class UpdateProductView(APIView):
|
|||||||
return Response({'code': 0, 'msg': '商品修改成功', 'data': {'id': product.id}})
|
return Response({'code': 0, 'msg': '商品修改成功', 'data': {'id': product.id}})
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateZhiKanShenheView(APIView):
|
||||||
|
"""
|
||||||
|
商品管理页:按俱乐部更新「只看审核商品」开关。
|
||||||
|
权限:2200a
|
||||||
|
POST /houtai/htxgzhikan
|
||||||
|
"""
|
||||||
|
permission_classes = []
|
||||||
|
parser_classes = [JSONParser]
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
username = request.data.get('username', '').strip()
|
||||||
|
if not username:
|
||||||
|
return Response({'code': 401, 'msg': '缺少username'})
|
||||||
|
|
||||||
|
kefu, permissions = verify_kefu_permission(request, username)
|
||||||
|
if kefu is None:
|
||||||
|
return permissions
|
||||||
|
if '2200a' not in permissions:
|
||||||
|
return Response({'code': 403, 'msg': '无权限管理商品'})
|
||||||
|
|
||||||
|
val = request.data.get('zhi_kan_shenhe')
|
||||||
|
if val is None:
|
||||||
|
return Response({'code': 400, 'msg': '缺少参数 zhi_kan_shenhe'})
|
||||||
|
|
||||||
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_context import resolve_club_scope
|
||||||
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
|
from shop.services.shenhe_config import get_or_create_shenhe_config
|
||||||
|
|
||||||
|
if resolve_club_scope(request) == DATA_SCOPE_ALL:
|
||||||
|
return Response({'code': 400, 'msg': '请先切换到具体俱乐部再修改只看审核开关'})
|
||||||
|
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
club_id = resolve_club_id_for_write(request)
|
||||||
|
config = get_or_create_shenhe_config(club_id)
|
||||||
|
config = DianpuShangpinShenheShezhi.objects.select_for_update().get(pk=config.pk)
|
||||||
|
config.zhi_kan_shenhe = bool(val)
|
||||||
|
config.save(update_fields=['zhi_kan_shenhe'])
|
||||||
|
return Response({
|
||||||
|
'code': 0,
|
||||||
|
'msg': '只看审核开关已更新',
|
||||||
|
'data': {'club_id': club_id, 'zhi_kan_shenhe': bool(val)},
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
logging.getLogger(__name__).exception('更新只看审核开关失败')
|
||||||
|
return Response({'code': 500, 'msg': '服务器错误'})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -421,17 +421,38 @@ class ShopPublicTypeAndAuditView(APIView):
|
|||||||
logger.exception("查询公共商品类型失败")
|
logger.exception("查询公共商品类型失败")
|
||||||
return Response({'code': 500, 'msg': '服务器错误,请稍后重试'})
|
return Response({'code': 500, 'msg': '服务器错误,请稍后重试'})
|
||||||
|
|
||||||
# ---------- 获取审核模式配置 ----------
|
# ---------- 获取本俱乐部审核模式配置 ----------
|
||||||
audit_config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
kaiqi_shenhe = audit_config.kaiqi_shenhe if audit_config else False
|
from shop.services.shenhe_config import get_or_create_shenhe_config
|
||||||
zhi_kan_shenhe = getattr(audit_config, 'zhi_kan_shenhe', True) if audit_config else True
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_context import resolve_club_scope
|
||||||
|
|
||||||
|
if resolve_club_scope(request) == DATA_SCOPE_ALL:
|
||||||
|
# 集团汇总:不自动创建,返回默认值提示前端切到具体俱乐部
|
||||||
|
return Response({
|
||||||
|
'code': 0,
|
||||||
|
'data': {
|
||||||
|
'public_types': type_list,
|
||||||
|
'kaiqi_shenhe': False,
|
||||||
|
'zhi_kan_shenhe': True,
|
||||||
|
'club_scoped': False,
|
||||||
|
'msg': '请切换到具体俱乐部查看/修改审核展示开关',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
club_id = resolve_club_id_for_write(request)
|
||||||
|
audit_config = get_or_create_shenhe_config(club_id)
|
||||||
|
kaiqi_shenhe = audit_config.kaiqi_shenhe
|
||||||
|
zhi_kan_shenhe = bool(getattr(audit_config, 'zhi_kan_shenhe', True))
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
'code': 0,
|
'code': 0,
|
||||||
'data': {
|
'data': {
|
||||||
'public_types': type_list,
|
'public_types': type_list,
|
||||||
'kaiqi_shenhe': kaiqi_shenhe,
|
'kaiqi_shenhe': kaiqi_shenhe,
|
||||||
'zhi_kan_shenhe': bool(zhi_kan_shenhe),
|
'zhi_kan_shenhe': zhi_kan_shenhe,
|
||||||
|
'club_id': club_id,
|
||||||
|
'club_scoped': True,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -640,18 +661,28 @@ class ShopProductModifyView(APIView):
|
|||||||
if kaiqi is None:
|
if kaiqi is None:
|
||||||
return Response({'code': 400, 'msg': '缺少参数 kaiqi_shenhe'})
|
return Response({'code': 400, 'msg': '缺少参数 kaiqi_shenhe'})
|
||||||
|
|
||||||
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_context import resolve_club_scope
|
||||||
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
|
from shop.services.shenhe_config import get_or_create_shenhe_config
|
||||||
|
|
||||||
|
if resolve_club_scope(request) == DATA_SCOPE_ALL:
|
||||||
|
return Response({'code': 400, 'msg': '请先切换到具体俱乐部再修改审核模式'})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config, _ = DianpuShangpinShenheShezhi.objects.select_for_update().get_or_create(id=1)
|
club_id = resolve_club_id_for_write(request)
|
||||||
|
config = get_or_create_shenhe_config(club_id)
|
||||||
|
config = DianpuShangpinShenheShezhi.objects.select_for_update().get(pk=config.pk)
|
||||||
config.kaiqi_shenhe = bool(kaiqi)
|
config.kaiqi_shenhe = bool(kaiqi)
|
||||||
config.save(update_fields=['kaiqi_shenhe'])
|
config.save(update_fields=['kaiqi_shenhe'])
|
||||||
return Response({'code': 0, 'msg': '审核模式已更新'})
|
return Response({'code': 0, 'msg': '审核模式已更新', 'data': {'club_id': club_id}})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("更新审核模式失败")
|
logger.exception("更新审核模式失败")
|
||||||
return Response({'code': 500, 'msg': '服务器错误'})
|
return Response({'code': 500, 'msg': '服务器错误'})
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def _update_zhi_kan_shenhe(self, request, user_perms):
|
def _update_zhi_kan_shenhe(self, request, user_perms):
|
||||||
"""点单端:未绑店用户是否按身份只看审核专用商品。"""
|
"""点单端:未绑店用户是否按身份只看审核专用商品(按俱乐部)。"""
|
||||||
if not has_perm_code(user_perms, '1199ab'):
|
if not has_perm_code(user_perms, '1199ab'):
|
||||||
return Response({'code': 403, 'msg': '无权限修改只看审核开关'})
|
return Response({'code': 403, 'msg': '无权限修改只看审核开关'})
|
||||||
|
|
||||||
@@ -659,11 +690,21 @@ class ShopProductModifyView(APIView):
|
|||||||
if val is None:
|
if val is None:
|
||||||
return Response({'code': 400, 'msg': '缺少参数 zhi_kan_shenhe'})
|
return Response({'code': 400, 'msg': '缺少参数 zhi_kan_shenhe'})
|
||||||
|
|
||||||
|
from jituan.constants import DATA_SCOPE_ALL
|
||||||
|
from jituan.services.club_context import resolve_club_scope
|
||||||
|
from jituan.services.club_write import resolve_club_id_for_write
|
||||||
|
from shop.services.shenhe_config import get_or_create_shenhe_config
|
||||||
|
|
||||||
|
if resolve_club_scope(request) == DATA_SCOPE_ALL:
|
||||||
|
return Response({'code': 400, 'msg': '请先切换到具体俱乐部再修改只看审核开关'})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config, _ = DianpuShangpinShenheShezhi.objects.select_for_update().get_or_create(id=1)
|
club_id = resolve_club_id_for_write(request)
|
||||||
|
config = get_or_create_shenhe_config(club_id)
|
||||||
|
config = DianpuShangpinShenheShezhi.objects.select_for_update().get(pk=config.pk)
|
||||||
config.zhi_kan_shenhe = bool(val)
|
config.zhi_kan_shenhe = bool(val)
|
||||||
config.save(update_fields=['zhi_kan_shenhe'])
|
config.save(update_fields=['zhi_kan_shenhe'])
|
||||||
return Response({'code': 0, 'msg': '只看审核开关已更新'})
|
return Response({'code': 0, 'msg': '只看审核开关已更新', 'data': {'club_id': club_id}})
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("更新只看审核开关失败")
|
logger.exception("更新只看审核开关失败")
|
||||||
return Response({'code': 500, 'msg': '服务器错误'})
|
return Response({'code': 500, 'msg': '服务器错误'})
|
||||||
|
|||||||
44
shop/migrations/0004_shenhe_shezhi_club_id.py
Normal file
44
shop/migrations/0004_shenhe_shezhi_club_id.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def forwards_fill_club_id(apps, schema_editor):
|
||||||
|
Model = apps.get_model('shop', 'DianpuShangpinShenheShezhi')
|
||||||
|
# 历史全局单例 → 归到星阙 xq;若已有多行则只保留一条
|
||||||
|
rows = list(Model.objects.all().order_by('id'))
|
||||||
|
if not rows:
|
||||||
|
return
|
||||||
|
keep = rows[0]
|
||||||
|
keep.club_id = keep.club_id or 'xq'
|
||||||
|
keep.save(update_fields=['club_id'])
|
||||||
|
for extra in rows[1:]:
|
||||||
|
extra.delete()
|
||||||
|
|
||||||
|
|
||||||
|
def noop_reverse(apps, schema_editor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('shop', '0003_zhi_kan_shenhe'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='dianpushangpinshenheshezhi',
|
||||||
|
name='club_id',
|
||||||
|
field=models.CharField(
|
||||||
|
db_index=True, default='xq', max_length=16, verbose_name='所属俱乐部',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.RunPython(forwards_fill_club_id, noop_reverse),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='dianpushangpinshenheshezhi',
|
||||||
|
name='club_id',
|
||||||
|
field=models.CharField(
|
||||||
|
db_index=True, default='xq', max_length=16, unique=True,
|
||||||
|
verbose_name='所属俱乐部',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -211,11 +211,14 @@ class ShangpinLeixingDianpu(QModel):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# shangdian/models.py 或独立应用 models.py
|
|
||||||
class DianpuShangpinShenheShezhi(QModel):
|
class DianpuShangpinShenheShezhi(QModel):
|
||||||
"""店铺商品审核模式全局配置(仅一条记录)"""
|
"""点单展示 / 店铺商品审核:按俱乐部各一条。"""
|
||||||
|
club_id = models.CharField(
|
||||||
|
max_length=16, unique=True, default='xq', db_index=True,
|
||||||
|
verbose_name='所属俱乐部',
|
||||||
|
)
|
||||||
kaiqi_shenhe = models.BooleanField(default=False, verbose_name='是否开启商品审核模式')
|
kaiqi_shenhe = models.BooleanField(default=False, verbose_name='是否开启商品审核模式')
|
||||||
# True=未注册打手等特殊身份时只看审核专用商品;False=未绑店一律看正常公共商品
|
# True=未绑店且无打手等身份只看审核专用;False=未绑店一律看正常公共商品
|
||||||
zhi_kan_shenhe = models.BooleanField(default=True, verbose_name='是否只看审核商品')
|
zhi_kan_shenhe = models.BooleanField(default=True, verbose_name='是否只看审核商品')
|
||||||
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||||
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||||
@@ -224,7 +227,3 @@ class DianpuShangpinShenheShezhi(QModel):
|
|||||||
db_table = 'dianpu_shangpin_shenhe_shezhi'
|
db_table = 'dianpu_shangpin_shenhe_shezhi'
|
||||||
verbose_name = '商品审核模式配置'
|
verbose_name = '商品审核模式配置'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
self.pk = 1 # 强制使用 ID=1 保证唯一
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|||||||
43
shop/services/shenhe_config.py
Normal file
43
shop/services/shenhe_config.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
"""点单端商品展示 / 店铺审核模式:按俱乐部隔离。"""
|
||||||
|
from jituan.constants import CLUB_ID_DEFAULT
|
||||||
|
from shop.models import DianpuShangpinShenheShezhi
|
||||||
|
|
||||||
|
|
||||||
|
def _norm_club_id(club_id):
|
||||||
|
return (club_id or CLUB_ID_DEFAULT).strip() or CLUB_ID_DEFAULT
|
||||||
|
|
||||||
|
|
||||||
|
def get_or_create_shenhe_config(club_id):
|
||||||
|
"""获取或创建某俱乐部的审核展示配置。"""
|
||||||
|
cid = _norm_club_id(club_id)
|
||||||
|
config, _ = DianpuShangpinShenheShezhi.objects.get_or_create(
|
||||||
|
club_id=cid,
|
||||||
|
defaults={
|
||||||
|
'kaiqi_shenhe': False,
|
||||||
|
'zhi_kan_shenhe': True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def is_zhi_kan_shenhe_enabled(club_id):
|
||||||
|
"""
|
||||||
|
未绑店用户是否只看审核专用商品。
|
||||||
|
无配置时默认 True,保持历史行为。
|
||||||
|
"""
|
||||||
|
config = DianpuShangpinShenheShezhi.query.filter(
|
||||||
|
club_id=_norm_club_id(club_id)
|
||||||
|
).first()
|
||||||
|
if not config:
|
||||||
|
return True
|
||||||
|
return bool(getattr(config, 'zhi_kan_shenhe', True))
|
||||||
|
|
||||||
|
|
||||||
|
def is_kaiqi_shenhe_enabled(club_id):
|
||||||
|
"""店铺发布商品是否需平台审核。无配置默认 False。"""
|
||||||
|
config = DianpuShangpinShenheShezhi.query.filter(
|
||||||
|
club_id=_norm_club_id(club_id)
|
||||||
|
).first()
|
||||||
|
if not config:
|
||||||
|
return False
|
||||||
|
return bool(config.kaiqi_shenhe)
|
||||||
@@ -139,22 +139,20 @@ class ShopGoodsView(APIView):
|
|||||||
# 店铺封禁或不属于当前俱乐部 → 公共正常商品
|
# 店铺封禁或不属于当前俱乐部 → 公共正常商品
|
||||||
data = self._get_public_goods(True)
|
data = self._get_public_goods(True)
|
||||||
else:
|
else:
|
||||||
# 未绑店:受「是否只看审核」开关控制
|
# 未绑店:受本俱乐部「是否只看审核」开关控制
|
||||||
# 开启 → 有特殊身份看正常(=1),否则看审核专用(=2)
|
# 开启 → 有特殊身份看正常(=1),否则看审核专用(=2)
|
||||||
# 关闭 → 一律看正常公共商品(与身份无关)
|
# 关闭 → 一律看正常公共商品(与身份无关)
|
||||||
use_normal = True
|
use_normal = True
|
||||||
if self._is_zhi_kan_shenhe_enabled():
|
if self._is_zhi_kan_shenhe_enabled(club_id):
|
||||||
use_normal = has_special
|
use_normal = has_special
|
||||||
data = self._get_public_goods(use_normal)
|
data = self._get_public_goods(use_normal)
|
||||||
|
|
||||||
return Response({'code': 200, 'data': data})
|
return Response({'code': 200, 'data': data})
|
||||||
|
|
||||||
def _is_zhi_kan_shenhe_enabled(self):
|
def _is_zhi_kan_shenhe_enabled(self, club_id):
|
||||||
"""全局开关:未绑店用户是否按身份只看审核专用商品。默认开启以保持历史行为。"""
|
"""本俱乐部开关:未绑店用户是否按身份只看审核专用商品。默认开启。"""
|
||||||
config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from shop.services.shenhe_config import is_zhi_kan_shenhe_enabled
|
||||||
if not config:
|
return is_zhi_kan_shenhe_enabled(club_id)
|
||||||
return True
|
|
||||||
return bool(getattr(config, 'zhi_kan_shenhe', True))
|
|
||||||
|
|
||||||
def _has_special_identity(self, user_main):
|
def _has_special_identity(self, user_main):
|
||||||
"""判断用户是否拥有打手/商家/管事/组长任一身份"""
|
"""判断用户是否拥有打手/商家/管事/组长任一身份"""
|
||||||
|
|||||||
@@ -237,9 +237,10 @@ class ShopProductModifyView(APIView):
|
|||||||
# 提取相对路径
|
# 提取相对路径
|
||||||
tupian_url = full_url.replace(settings.COS_DOMAIN.rstrip('/') + '/', '', 1)
|
tupian_url = full_url.replace(settings.COS_DOMAIN.rstrip('/') + '/', '', 1)
|
||||||
|
|
||||||
# 审核状态
|
# 审核状态(按店铺所属俱乐部)
|
||||||
audit_config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from shop.services.shenhe_config import is_kaiqi_shenhe_enabled
|
||||||
shenhe_status = not (audit_config and audit_config.kaiqi_shenhe)
|
shop_club = getattr(dianpu, 'club_id', None) or 'xq'
|
||||||
|
shenhe_status = not is_kaiqi_shenhe_enabled(shop_club)
|
||||||
|
|
||||||
ShangpinLeixingDianpu.query.create(
|
ShangpinLeixingDianpu.query.create(
|
||||||
dianpu_id=dianpu.id,
|
dianpu_id=dianpu.id,
|
||||||
@@ -320,8 +321,9 @@ class ShopProductModifyView(APIView):
|
|||||||
|
|
||||||
# 审核重置
|
# 审核重置
|
||||||
if content_changed:
|
if content_changed:
|
||||||
audit_config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from shop.services.shenhe_config import is_kaiqi_shenhe_enabled
|
||||||
if audit_config and audit_config.kaiqi_shenhe:
|
shop_club = getattr(dianpu, 'club_id', None) or 'xq'
|
||||||
|
if is_kaiqi_shenhe_enabled(shop_club):
|
||||||
obj.shenhe_zhuangtai = False
|
obj.shenhe_zhuangtai = False
|
||||||
update_fields.append('shenhe_zhuangtai')
|
update_fields.append('shenhe_zhuangtai')
|
||||||
|
|
||||||
@@ -872,8 +874,9 @@ class ShopProductModifyView1(APIView):
|
|||||||
content_changed = True
|
content_changed = True
|
||||||
|
|
||||||
if content_changed:
|
if content_changed:
|
||||||
audit_config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from shop.services.shenhe_config import is_kaiqi_shenhe_enabled
|
||||||
if audit_config and audit_config.kaiqi_shenhe:
|
shop_club = getattr(dianpu, 'club_id', None) or 'xq'
|
||||||
|
if is_kaiqi_shenhe_enabled(shop_club):
|
||||||
product.shenhe_zhuangtai = False
|
product.shenhe_zhuangtai = False
|
||||||
update_fields.append('shenhe_zhuangtai')
|
update_fields.append('shenhe_zhuangtai')
|
||||||
|
|
||||||
@@ -962,8 +965,9 @@ class ShopProductModifyView1(APIView):
|
|||||||
return Response({'code': 400, 'msg': '分成金额不能超过商品价格'})'''
|
return Response({'code': 400, 'msg': '分成金额不能超过商品价格'})'''
|
||||||
|
|
||||||
shenhe_status = True
|
shenhe_status = True
|
||||||
audit_config = DianpuShangpinShenheShezhi.query.filter(id=1).first()
|
from shop.services.shenhe_config import is_kaiqi_shenhe_enabled
|
||||||
if audit_config and audit_config.kaiqi_shenhe:
|
shop_club = getattr(dianpu, 'club_id', None) or 'xq'
|
||||||
|
if is_kaiqi_shenhe_enabled(shop_club):
|
||||||
shenhe_status = False
|
shenhe_status = False
|
||||||
|
|
||||||
product = Shangpin.query.create(
|
product = Shangpin.query.create(
|
||||||
|
|||||||
Reference in New Issue
Block a user