diff --git a/apps/brands/views.py b/apps/brands/views.py index 2bea480..92ae8ab 100644 --- a/apps/brands/views.py +++ b/apps/brands/views.py @@ -5,6 +5,7 @@ from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from apps.user.authentication import CustomTokenAuthentication import logging +from django.db.models import Q from .models import Brand, Product, Campaign, BrandChatSession from .serializers import ( @@ -94,6 +95,23 @@ class BrandViewSet(viewsets.ModelViewSet): brand = self.get_object() return api_response(data={'dataset_id_list': brand.dataset_id_list}) + @action(detail=False, methods=['get']) + def search(self, request): + """关键字搜索品牌""" + keyword = request.query_params.get('keyword', '') + if not keyword: + return api_response(code=400, message="缺少关键字参数", data=None) + + queryset = self.get_queryset().filter( + Q(name__icontains=keyword) | + Q(description__icontains=keyword) | + Q(category__icontains=keyword) | + Q(source__icontains=keyword) + ) + + serializer = self.get_serializer(queryset, many=True) + return api_response(data=serializer.data) + class ProductViewSet(viewsets.ModelViewSet): """产品API视图集""" @@ -172,6 +190,23 @@ class ProductViewSet(viewsets.ModelViewSet): brand.dataset_id_list.remove(instance.dataset_id) brand.save(update_fields=['dataset_id_list', 'updated_at']) + @action(detail=False, methods=['get']) + def search(self, request): + """关键字搜索产品""" + keyword = request.query_params.get('keyword', '') + if not keyword: + return api_response(code=400, message="缺少关键字参数", data=None) + + queryset = self.get_queryset().filter( + Q(name__icontains=keyword) | + Q(description__icontains=keyword) | + Q(pid__icontains=keyword) | + Q(brand__name__icontains=keyword) + ) + + serializer = self.get_serializer(queryset, many=True) + return api_response(data=serializer.data) + class CampaignViewSet(viewsets.ModelViewSet): """活动API视图集""" @@ -737,6 +772,27 @@ class CampaignViewSet(viewsets.ModelViewSet): return api_response(data={"websocket_url": ws_url}) + @action(detail=False, methods=['get']) + def search(self, request): + """关键字搜索活动""" + keyword = request.query_params.get('keyword', '') + if not keyword: + return api_response(code=400, message="缺少关键字参数", data=None) + + queryset = self.get_queryset().filter( + Q(name__icontains=keyword) | + Q(description__icontains=keyword) | + Q(service__icontains=keyword) | + Q(creator_type__icontains=keyword) | + Q(creator_level__icontains=keyword) | + Q(creator_category__icontains=keyword) | + Q(brand__name__icontains=keyword) | + Q(status__icontains=keyword) + ) + + serializer = self.get_serializer(queryset, many=True) + return api_response(data=serializer.data) + class BrandChatSessionViewSet(viewsets.ModelViewSet): """品牌聊天会话API视图集""" diff --git a/apps/discovery/views.py b/apps/discovery/views.py index ccddad6..b623a31 100644 --- a/apps/discovery/views.py +++ b/apps/discovery/views.py @@ -117,6 +117,124 @@ class SearchSessionViewSet(viewsets.ModelViewSet): return ApiResponse.success(result, "获取会话摘要列表成功") + @action(detail=False, methods=['get']) + def search(self, request): + """搜索会话""" + keyword = request.query_params.get('keyword', '') + if not keyword: + return ApiResponse.error("缺少关键字参数", code=400) + + queryset = self.get_queryset() + + # 尝试判断关键字是否是日期格式 + is_date = False + parsed_date = None + + # 支持多种日期格式 + date_formats = [ + '%Y-%m-%d', + '%Y/%m/%d', + '%d-%m-%Y', + '%d/%m/%Y', + '%m-%d-%Y', + '%m/%d/%Y' + ] + + for fmt in date_formats: + try: + from datetime import datetime + parsed_date = datetime.strptime(keyword, fmt).date() + is_date = True + break + except ValueError: + continue + + # 构建查询条件 + if is_date: + # 如果是完整日期格式,按日期搜索 + queryset = queryset.filter(date_created=parsed_date) + else: + # 检查是否可能是年份 + is_year = False + year_value = None + try: + # 尝试将关键字作为年份处理 + if len(keyword) == 4 and keyword.isdigit(): + year_value = int(keyword) + if 1900 <= year_value <= 2100: # 合理的年份范围 + is_year = True + # 按年份搜索 + from django.db.models.functions import Extract + queryset = queryset.annotate(year=Extract('date_created', 'year')).filter(year=year_value) + except Exception: + is_year = False + + # 如果不是年份,继续其他搜索逻辑 + if not is_year: + try: + # 尝试将关键字转换为整数(用于ID或会话编号) + keyword_int = int(keyword) + queryset = queryset.filter( + Q(id=keyword_int) | + Q(session_number=keyword_int) + ) + except ValueError: + # 如果转换失败,则按其他可能的字符串字段搜索 + queryset = queryset.filter( + Q(id__icontains=keyword) | + Q(session_number__icontains=keyword) + ) + + # 额外尝试对日期的部分进行模糊匹配 + try: + # 如果关键字可能是月份名称或数字 + month_names = { + '一月': 1, '二月': 2, '三月': 3, '四月': 4, '五月': 5, '六月': 6, + '七月': 7, '八月': 8, '九月': 9, '十月': 10, '十一月': 11, '十二月': 12, + 'january': 1, 'february': 2, 'march': 3, 'april': 4, 'may': 5, 'june': 6, + 'july': 7, 'august': 8, 'september': 9, 'october': 10, 'november': 11, 'december': 12, + 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'jun': 6, 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12 + } + + month_value = None + # 检查是否是月份名称 + lower_keyword = keyword.lower() + if lower_keyword in month_names: + month_value = month_names[lower_keyword] + # 检查是否是数字月份 + elif keyword.isdigit() and 1 <= int(keyword) <= 12: + month_value = int(keyword) + + if month_value: + # 按月份搜索 + from django.db.models.functions import Extract + month_queryset = self.get_queryset().annotate(month=Extract('date_created', 'month')).filter(month=month_value) + # 合并查询结果 + queryset = queryset | month_queryset + except Exception: + # 忽略任何错误,继续使用之前的查询集 + pass + + # 如果没有找到结果 + if not queryset.exists(): + return ApiResponse.error(f"未找到匹配关键词 '{keyword}' 的会话", code=404) + + # 格式化响应数据 + result = [] + for session in queryset: + result.append({ + 'id': session.id, + 'session_number': session.session_number, + 'date': session.date_created, + 'creator_count': session.creator_count, + 'shoppable_creators': session.shoppable_creators, + 'avg_followers': session.avg_followers, + 'avg_gmv': session.avg_gmv, + 'avg_video_views': session.avg_video_views + }) + + return ApiResponse.success(result, f"搜索会话成功,关键词: {keyword}") + class CreatorDiscoveryViewSet(viewsets.ReadOnlyModelViewSet): """创作者发现视图集"""