feat: 会员/履约金页文案按俱乐部可配置

新增 club_recharge_page_copy 表与小程序/后台读写接口,kefu 菜单挂「充值页文案」。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-24 00:04:23 +08:00
parent dcb191ac3a
commit 4b5130c824
7 changed files with 402 additions and 1 deletions

View File

@@ -0,0 +1,138 @@
"""会员/履约金页文案:小程序只读 + 客服后台读写。"""
from rest_framework.parsers import JSONParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from backend.utils import verify_kefu_permission
from jituan.services.display_config import forbid_display_write_in_all_scope, list_response_meta
from jituan.services.recharge_page_copy import (
PAGE_KEYS,
club_id_for_admin,
club_id_for_mini,
get_admin_regions,
get_public_regions,
normalize_page_key,
save_region,
)
POPUP_PERM = '8080a'
def _page_key_from_request(request):
if hasattr(request, 'query_params'):
q = request.query_params.get('page_key')
if q:
return q
data = getattr(request, 'data', None) or {}
return data.get('page_key') or ''
class RechargePageCopyView(APIView):
"""小程序只读 GET/POST /jituan/recharge-page-copy?page_key=huiyuan|yajin"""
permission_classes = [IsAuthenticated]
parser_classes = [JSONParser]
def get(self, request):
return self._handle(request)
def post(self, request):
return self._handle(request)
def _handle(self, request):
page_key = normalize_page_key(_page_key_from_request(request))
if not page_key:
return Response({'code': 400, 'msg': f'page_key 须为 {", ".join(sorted(PAGE_KEYS))}'})
club_id = club_id_for_mini(request)
regions = get_public_regions(club_id, page_key)
return Response({
'code': 0,
'data': {
'page_key': page_key,
'club_id': club_id,
'regions': regions,
},
})
class RechargePageCopyAdminGetView(APIView):
"""后台拉全量区域 POST /jituan/houtai/recharge-page-copy/get"""
permission_classes = [IsAuthenticated]
parser_classes = [JSONParser]
def post(self, request):
phone = (request.data.get('phone') or request.data.get('username') or '').strip()
if not phone:
return Response({'code': 401, 'msg': '缺少客服账号'})
kefu, permissions = verify_kefu_permission(request, phone)
if kefu is None:
return permissions
if POPUP_PERM not in permissions:
return Response({'code': 403, 'msg': '无权限管理充值页文案'})
page_key = normalize_page_key(request.data.get('page_key'))
if not page_key:
return Response({'code': 400, 'msg': f'page_key 须为 {", ".join(sorted(PAGE_KEYS))}'})
club_id = club_id_for_admin(request, request.user)
regions = get_admin_regions(club_id, page_key)
return Response({
'code': 0,
'data': {
'page_key': page_key,
'club_id': club_id,
'regions': regions,
**list_response_meta(request),
},
})
class RechargePageCopyAdminSaveView(APIView):
"""后台保存某一区域 POST /jituan/houtai/recharge-page-copy/save"""
permission_classes = [IsAuthenticated]
parser_classes = [JSONParser]
def post(self, request):
phone = (request.data.get('phone') or request.data.get('username') or '').strip()
if not phone:
return Response({'code': 401, 'msg': '缺少客服账号'})
kefu, permissions = verify_kefu_permission(request, phone)
if kefu is None:
return permissions
if POPUP_PERM not in permissions:
return Response({'code': 403, 'msg': '无权限管理充值页文案'})
deny = forbid_display_write_in_all_scope(request)
if deny:
return deny
page_key = request.data.get('page_key')
region_key = request.data.get('region_key')
title = request.data.get('title') or ''
items = request.data.get('items')
if items is None:
items = request.data.get('items_json')
enabled = request.data.get('enabled', True)
sort_order = request.data.get('sort_order')
club_id = club_id_for_admin(request, request.user)
data, err = save_region(
club_id,
page_key,
region_key,
title=title,
items=items,
enabled=enabled,
sort_order=sort_order,
)
if err:
return Response({'code': 400, 'msg': err})
return Response({
'code': 0,
'msg': '保存成功',
'data': {
'page_key': normalize_page_key(page_key),
'club_id': club_id,
'region': data,
},
})