import logging from django.utils.translation import gettext as _ from django.utils import timezone from django.db import models from rest_framework.response import Response from rest_framework.permissions import IsAdminUser from rest_framework.exceptions import NotFound from rest_framework.throttling import ScopedRateThrottle from pingcap_sso.api.base import AdminEndpoint from pingcap_sso.api.permissions import MethodPermission from pingcap_sso.models import ( User, PointProduct, PointProductRedemptionRecord ) from pingcap_sso.forms.admin_point import ( AdminManualAwardPointForm, AdminBulkAwardPointForm ) logger = logging.getLogger(__name__) class ProductListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.manage_points_system'], 'POST': ['pingcap_sso.manage_points_system'], } def get(self, request, *args, **kwargs): """audit_log: 获取了积分 - 礼品列表""" return Response({ 'detail': _('success'), 'data': [{ 'id': p.id, 'name': p.name, 'cover_url': p.cover_url, 'points': p.points, 'amount': p.amount, 'remains': p.remains, 'pe_exchange_code_id': p.pe_exchange_code_id, 'redeemed': p.pointproductredemptionrecord_set.count() } for p in PointProduct.objects.filter( deleted_by_user__isnull=True).order_by('sort_order')] }) def post(self, request, *args, **kwargs): """audit_log: 新增了积分 - 礼品""" data = request.data PointProduct.objects.create( name=data.get('name'), cover_url=data.get('cover_url'), points=data.get('points'), amount=data.get('amount'), remains=data.get('amount'), pe_exchange_code_id=data.get('pe_exchange_code_id'), ) return Response({ 'detail': _('success') }) class ProductEditEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'POST': ['pingcap_sso.manage_points_system'], 'DELETE': ['pingcap_sso.manage_points_system'], } def post(self, request, *args, **kwargs): """audit_log: 更新了积分 - 礼品""" data = request.data product = PointProduct.objects.get(pk=data.get('id')) product.name = data.get('name') product.cover_url = data.get('cover_url') product.points = data.get('points') product.remains = models.F('remains') + int(data.get('amount')) product.pe_exchange_code_id = data.get('pe_exchange_code_id') or None product.save() return Response({ 'detail': _('success') }) def delete(self, request, *args, **kwargs): """audit_log: 删除了积分 - 礼品""" data = request.data product = PointProduct.objects.get(pk=data.get('id')) product.deleted_by_user = request.user product.deleted_at = timezone.now() product.save() return Response({ 'detail': _('success') }) class ProductReorderEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'POST': ['pingcap_sso.manage_points_system'] } def post(self, request, *args, **kwargs): """audit_log: 调整了积分 - 礼品展示顺序""" try: product_id = request.data.get('product_id') direction = request.data.get('direction', 1) product = PointProduct.objects.get(id=product_id) except PointProduct.DoesNotExist: raise NotFound except Exception: return Response({ 'detail': _('wrong params') }, 400) product_ids = list(PointProduct.objects.all().order_by( 'sort_order').values_list('id', flat=True)) product_order_map = {d[1]: d[0] for d in enumerate(product_ids)} order_product_map = {d[0]: d[1] for d in enumerate(product_ids)} current_product_rank = product_order_map[product_id] if direction > 0: product_order_map[product_id] = current_product_rank - 1 if order_product_map.get(current_product_rank - 1): product_order_map[order_product_map[current_product_rank - 1]] = current_product_rank else: product_order_map[product_id] = current_product_rank + 1 if order_product_map.get(current_product_rank + 1): product_order_map[order_product_map[current_product_rank + 1]] = current_product_rank for product_id, order in product_order_map.items(): PointProduct.objects.filter(id=product_id).update(sort_order=order) return Response({ 'detail': _('success') }) class OrderListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.manage_points_system'] } def get(self, request, *args, **kwargs): """audit_log: 查看了积分 - 订单列表""" try: cur_page = int(request.GET.get('currentPage', 1)) per_page = int(request.GET.get('perPage', 10)) search = request.GET.get('search', '') except Exception: return Response({ 'detail': _('wrong params') }, 400) qs = PointProductRedemptionRecord.objects.all().order_by('-created_at') total_num = qs.count() qs = qs[(cur_page - 1) * per_page:cur_page * per_page] data = list() for o in qs: data.append({ 'id': o.id, 'username': o.user.username, 'product_name': o.product.name, 'points': o.points, 'consignee_name': o.consignee_name, 'consignee_phone': o.consignee_phone, 'consignee_addrss': o.consignee_addrss, 'comment': o.comment, 'courier_company': o.courier_company, 'tracking_number': o.tracking_number, 'created_at': timezone.localtime(o.created_at).strftime('%Y-%m-%d %H:%M') }) return Response({ 'detail': _('success'), 'data': data, 'total_num': total_num, 'per_page': per_page, 'cur_page': cur_page }) class OrderEditLogisticsEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'POST': ['pingcap_sso.manage_points_system'] } def post(self, request, *args, **kwargs): """audit_log: 更新了积分 - 订单物流详情""" data = request.data order = PointProductRedemptionRecord.objects.get(pk=data.get('id')) order.courier_company = data.get('courier_company') order.tracking_number = data.get('tracking_number') order.save() return Response({ 'detail': _('success') }) class UserAwardedListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.manage_points_system'] } def get(self, request, *args, **kwargs): """audit_log: 查看了用户积分记录列表""" try: user = User.objects.get(username=kwargs['username']) cur_page = int(request.GET.get('currentPage', 1)) per_page = int(request.GET.get('perPage', 10)) except User.DoesNotExist: raise NotFound except Exception: return Response({ 'detail': _('wrong params') }, 400) records = user.awardedpoint_records.all().order_by('-created_at') total_num = records.count() records = records[(cur_page - 1) * per_page:cur_page * per_page] return Response({ 'detail': _('success'), 'data': [{ 'digest': r.digest, 'points': r.points, 'exps': r.experience, 'comment': r.comment, 'reason': r.reason, 'created_at': timezone.localtime(r.created_at).strftime('%Y-%m-%d') } for r in records], 'total_num': total_num, 'per_page': per_page, 'cur_page': cur_page }) class UserRedeemListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.manage_points_system'] } def get(self, request, *args, **kwargs): """audit_log: 查看了用户礼品兑换列表""" try: user = User.objects.get(username=kwargs['username']) cur_page = int(request.GET.get('currentPage', 1)) per_page = int(request.GET.get('perPage', 10)) except User.DoesNotExist: raise NotFound except Exception: return Response({ 'detail': _('wrong params') }, 400) records = user.pointredemptionrecords.all().order_by('-created_at') total_num = records.count() records = records[(cur_page - 1) * per_page:cur_page * per_page] return Response({ 'detail': _('success'), 'data': [{ 'product_id': r.product.id, 'product_name': r.product.name, 'points': r.points, 'consignee_name': r.consignee_name, 'consignee_phone': r.consignee_phone, 'consignee_addrss': r.consignee_addrss, 'comment': r.comment, 'courier_company': r.courier_company, 'tracking_number': r.tracking_number, 'created_at': timezone.localtime(r.created_at).strftime('%Y-%m-%d/%H:%M') } for r in records], 'total_num': total_num, 'per_page': per_page, 'cur_page': cur_page }) class ManualAwardEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'POST': ['pingcap_sso.manage_points_system'] } throttle_classes = (ScopedRateThrottle, ) throttle_scope = 'admin' def post(self, request, *args, **kwargs): """audit_log: 对用户进行了积分奖励""" try: user = User.objects.get( models.Q( username=kwargs['username'] ) | models.Q( openid=kwargs['username'] ) ) except User.DoesNotExist: raise NotFound form = AdminManualAwardPointForm( target_user=user, staff=request.user, data=request.data) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success') }) class BulkAwardEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'POST': ['pingcap_sso.manage_points_system'] } def post(self, request, *args, **kwargs): """audit_log: 对批量用户进行了积分奖励""" form = AdminBulkAwardPointForm( staff=request.user, data=request.data) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success'), 'data': { 'users': form.users.values_list('username', flat=True), 'exps': form.cleaned_data['exps'], 'points': form.cleaned_data['points'], 'reason': form.cleaned_data['reason'], 'digest': form.cleaned_data['digest'] } })