197 lines
7.4 KiB
Python
197 lines
7.4 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 _parse_date(value):
|
|
if not value:
|
|
return None
|
|
from datetime import date
|
|
if isinstance(value, date):
|
|
return value
|
|
text = str(value).strip()[:10]
|
|
if not text:
|
|
return None
|
|
try:
|
|
return date.fromisoformat(text)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
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),
|
|
'activity_start': scheme.activity_start.isoformat() if scheme.activity_start else '',
|
|
'activity_end': scheme.activity_end.isoformat() if scheme.activity_end else '',
|
|
'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': '请配置至少一个奖励档位'})
|
|
|
|
activity_start = _parse_date(data.get('activity_start'))
|
|
activity_end = _parse_date(data.get('activity_end'))
|
|
if activity_start and activity_end and activity_start > activity_end:
|
|
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,
|
|
'activity_start': activity_start,
|
|
'activity_end': activity_end,
|
|
},
|
|
)
|
|
|
|
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}})
|