Files
Django/rank/reward_houtai_views.py
XingQue 5ef4ff7c91 feat: 排行榜奖励按俱乐部分奖与手动领取
- 新增奖励方案/档位/结算/领取四表与懒结算服务
- 小程序 phbjlxx/phbjllq/phbjlphb 新接口,phbhqsj 零改动
- 后台 phbjhq/phbjbc/phbjjl 与 phbj666 权限菜单

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 17:40:56 +08:00

173 lines
6.5 KiB
Python

"""排行榜奖励 — 后台 kefu API。"""
import logging
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.club_context import resolve_club_id_from_request
from jituan.services.display_config import forbid_display_write_in_all_scope
from rank.reward_models import RankRewardClaim, RankRewardScheme, RankRewardTier
from rank.reward_services import SORT_FIELD_REGISTRY, sort_field_options_for_shenfen
logger = logging.getLogger(__name__)
REWARD_PERMS = ('phbj666', '8080a')
def _has_perm(permissions):
return any(p in permissions for p in REWARD_PERMS)
def _serialize_scheme(scheme):
tiers = RankRewardTier.query.filter(scheme_id=scheme.id).order_by('rank_from')
return {
'id': scheme.id,
'club_id': scheme.club_id,
'shenfen': scheme.shenfen,
'period_type': scheme.period_type,
'sort_field': scheme.sort_field,
'sort_options': sort_field_options_for_shenfen(scheme.shenfen),
'title': scheme.title,
'description': scheme.description,
'enabled': scheme.enabled,
'claim_days': scheme.claim_days,
'min_metric': float(scheme.min_metric or 0),
'tiers': [
{
'id': t.id,
'rank_from': t.rank_from,
'rank_to': t.rank_to,
'reward_amount': float(t.reward_amount),
'label': t.label,
}
for t in tiers
],
}
class RankRewardHoutaiListView(APIView):
"""POST /houtai/phbjhq"""
permission_classes = [IsAuthenticated]
def post(self, request):
username = request.data.get('username')
kefu, permissions = verify_kefu_permission(request, username)
if kefu is None:
return Response({'code': 403, 'msg': '身份验证失败'})
if not _has_perm(permissions):
return Response({'code': 403, 'msg': '无排行榜奖励配置权限'})
club_id = resolve_club_id_from_request(request)
schemes = RankRewardScheme.query.filter(club_id=club_id).order_by('shenfen', 'period_type')
return Response({
'code': 0,
'data': {
'club_id': club_id,
'schemes': [_serialize_scheme(s) for s in schemes],
'shenfen_options': list(SORT_FIELD_REGISTRY.keys()),
'period_options': [
{'key': RankRewardScheme.PERIOD_DAY, 'label': '日榜(昨日)'},
{'key': RankRewardScheme.PERIOD_WEEK, 'label': '周榜(上周)'},
{'key': RankRewardScheme.PERIOD_MONTH, 'label': '月榜(上月)'},
],
},
})
class RankRewardHoutaiSaveView(APIView):
"""POST /houtai/phbjbc"""
permission_classes = [IsAuthenticated]
def post(self, request):
username = request.data.get('username')
kefu, permissions = verify_kefu_permission(request, username)
if kefu is None:
return Response({'code': 403, 'msg': '身份验证失败'})
if not _has_perm(permissions):
return Response({'code': 403, 'msg': '无权限'})
deny = forbid_display_write_in_all_scope(request)
if deny:
return deny
club_id = resolve_club_id_from_request(request)
data = request.data
shenfen = (data.get('shenfen') or '').strip()
period_type = (data.get('period_type') or '').strip()
sort_field = (data.get('sort_field') or '').strip()
if shenfen not in SORT_FIELD_REGISTRY:
return Response({'code': 400, 'msg': '身份无效'})
if period_type not in (RankRewardScheme.PERIOD_DAY, RankRewardScheme.PERIOD_WEEK, RankRewardScheme.PERIOD_MONTH):
return Response({'code': 400, 'msg': '周期无效'})
if sort_field not in SORT_FIELD_REGISTRY[shenfen]:
return Response({'code': 400, 'msg': '排序指标无效'})
tiers = data.get('tiers') or []
if not tiers:
return Response({'code': 400, 'msg': '请配置至少一个奖励档位'})
scheme, _ = RankRewardScheme.objects.update_or_create(
club_id=club_id,
shenfen=shenfen,
period_type=period_type,
defaults={
'sort_field': sort_field,
'title': (data.get('title') or '').strip(),
'description': (data.get('description') or '').strip(),
'enabled': bool(data.get('enabled', False)),
'claim_days': int(data.get('claim_days') or 30),
'min_metric': data.get('min_metric') or 0,
},
)
RankRewardTier.query.filter(scheme_id=scheme.id).delete()
for t in tiers:
RankRewardTier.query.create(
scheme_id=scheme.id,
rank_from=int(t['rank_from']),
rank_to=int(t['rank_to']),
reward_amount=t['reward_amount'],
label=(t.get('label') or '').strip(),
)
return Response({'code': 0, 'msg': '保存成功', 'data': _serialize_scheme(scheme)})
class RankRewardHoutaiClaimsView(APIView):
"""POST /houtai/phbjjl 领取明细"""
permission_classes = [IsAuthenticated]
def post(self, request):
username = request.data.get('username')
kefu, permissions = verify_kefu_permission(request, username)
if kefu is None:
return Response({'code': 403, 'msg': '身份验证失败'})
if not _has_perm(permissions):
return Response({'code': 403, 'msg': '无权限'})
club_id = resolve_club_id_from_request(request)
status = request.data.get('status')
qs = RankRewardClaim.query.filter(club_id=club_id).order_by('-CreateTime')[:100]
if status is not None:
qs = qs.filter(status=int(status))
status_map = {0: '待领取', 1: '已领取', 2: '已过期', 3: '已取消'}
items = [
{
'id': c.id,
'yonghuid': c.yonghuid,
'shenfen': c.shenfen,
'mingci': c.mingci,
'amount': float(c.reward_amount),
'status': c.status,
'status_text': status_map.get(c.status, ''),
'claimed_at': c.claimed_at.isoformat() if c.claimed_at else '',
'CreateTime': c.CreateTime.isoformat() if c.CreateTime else '',
}
for c in qs
]
return Response({'code': 0, 'data': {'list': items}})