From d899ec76ade9db2647fa4d7d0e9075577ea64cae Mon Sep 17 00:00:00 2001 From: jlj <3042504846@qq.com> Date: Thu, 5 Jun 2025 15:43:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=93=81=E7=89=8C=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/daren_detail/urls.py | 2 + apps/daren_detail/views.py | 154 +++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/apps/daren_detail/urls.py b/apps/daren_detail/urls.py index bdb8ac3..68e9242 100644 --- a/apps/daren_detail/urls.py +++ b/apps/daren_detail/urls.py @@ -35,6 +35,8 @@ urlpatterns = [ # 添加Campaign相关API path('campaigns/', views.get_campaigns, name='get_campaigns'), path('campaigns/add/', views.add_to_campaign, name='add_to_campaign'), + # 新增品牌合作活动列表API + path('brand/campaigns/', views.get_brand_campaigns, name='get_brand_campaigns'), # 新增的指标相关API path('creators//metrics/', views.get_creator_metrics, name='get_creator_metrics'), diff --git a/apps/daren_detail/views.py b/apps/daren_detail/views.py index f075735..a0bf860 100644 --- a/apps/daren_detail/views.py +++ b/apps/daren_detail/views.py @@ -3856,6 +3856,160 @@ def search_private_creators(request): }, json_dumps_params={'ensure_ascii': False}) +@api_view(['GET']) +@authentication_classes([CustomTokenAuthentication]) +@csrf_exempt +@require_http_methods(["GET"]) +def get_brand_campaigns(request): + """获取品牌合作活动列表,必须指定达人ID""" + try: + from apps.brands.models import Campaign, Brand, Product + from .models import CreatorCampaign, CreatorProfile + + # 获取分页参数 + page = int(request.GET.get('page', 1)) + page_size = int(request.GET.get('page_size', 10)) + + # 获取过滤参数 + brand_id = request.GET.get('brand_id') + status = request.GET.get('status') + creator_id = request.GET.get('creator_id') + + # 验证creator_id参数是否提供 + if not creator_id: + return JsonResponse({ + 'code': 400, + 'message': '缺少必要参数: creator_id', + 'data': None + }, json_dumps_params={'ensure_ascii': False}) + + # 验证达人是否存在 + try: + creator = CreatorProfile.objects.get(id=creator_id) + + # 获取该达人参与的所有活动ID + creator_campaigns = CreatorCampaign.objects.filter(creator=creator) + campaign_ids = [cc.campaign_id for cc in creator_campaigns] + + # 基础查询 - 筛选该达人参与的活动 + campaigns_query = Campaign.objects.filter(is_active=True, id__in=campaign_ids) + except CreatorProfile.DoesNotExist: + return JsonResponse({ + 'code': 404, + 'message': f'未找到ID为 {creator_id} 的达人', + 'data': None + }, json_dumps_params={'ensure_ascii': False}) + + # 应用品牌过滤 + if brand_id: + campaigns_query = campaigns_query.filter(brand_id=brand_id) + + # 应用状态过滤 + if status: + campaigns_query = campaigns_query.filter(status=status) + + # 获取总数据量 + total_count = campaigns_query.count() + + # 计算分页 + start = (page - 1) * page_size + end = start + page_size + + # 执行查询并分页 + campaigns = campaigns_query.order_by('-created_at')[start:end] + + campaign_list = [] + for campaign in campaigns: + # 获取品牌信息和首字母 + if isinstance(campaign.brand, Brand): + brand_name = campaign.brand.name + brand_id_str = str(campaign.brand.id) + else: + brand_name = str(campaign.brand) if campaign.brand else "" + brand_id_str = "" + + # 获取品牌首字母用于显示 + first_letter = brand_name[:1].upper() if brand_name else "" + + # 构造品牌信息 + brand_info = { + "id": brand_id_str, + "name": brand_name, + "first_letter": first_letter + } + + # 格式化时间 + start_date = campaign.start_date.strftime('%m/%d/%Y') if campaign.start_date else "" + end_date = campaign.end_date.strftime('%m/%d/%Y') if campaign.end_date else "" + + # 获取价格信息 + price_detail = "" + if campaign.budget: + if isinstance(campaign.budget, str): + # 如果已经是字符串且包含$符号,直接使用 + if '$' in campaign.budget: + price_detail = campaign.budget + else: + price_detail = f"${campaign.budget}" + else: + # 如果是数字,格式化为带$的字符串 + price_detail = f"${campaign.budget}" + + # 格式化GMV和观看量 + gmv_achieved = campaign.gmv_achieved or "" + views_achieved = campaign.views_achieved or "" + + # 获取该达人在此活动中的状态 + try: + creator_campaign = CreatorCampaign.objects.get(creator_id=creator_id, campaign=campaign) + status_value = creator_campaign.status + except CreatorCampaign.DoesNotExist: + status_value = "" + + # 构造活动数据 - 精确匹配图片中的表格列 + campaign_data = { + "brand": brand_info, + "pricing_detail": price_detail, + "start_date": start_date, + "end_date": end_date, + "status": status_value, + "gmv_achieved": gmv_achieved, + "views_achieved": views_achieved, + "video_link": campaign.video_link or "" + } + + campaign_list.append(campaign_data) + + # 计算总页数 + total_pages = (total_count + page_size - 1) // page_size + + # 构造分页信息 + pagination = { + "current_page": page, + "total_pages": total_pages, + "total_count": total_count, + "has_next": page < total_pages, + "has_prev": page > 1 + } + + return JsonResponse({ + 'code': 200, + 'message': '获取成功', + 'data': campaign_list, + 'pagination': pagination + }, json_dumps_params={'ensure_ascii': False}) + + except Exception as e: + logger.error(f"获取品牌合作活动列表失败: {e}") + import traceback + logger.error(f"详细错误: {traceback.format_exc()}") + return JsonResponse({ + 'code': 500, + 'message': f'获取品牌合作活动列表失败: {str(e)}', + 'data': None + }, json_dumps_params={'ensure_ascii': False}) + +