diff --git a/apps/brands/views.py b/apps/brands/views.py index 92ae8ab..51e4345 100644 --- a/apps/brands/views.py +++ b/apps/brands/views.py @@ -398,8 +398,8 @@ class CampaignViewSet(viewsets.ModelViewSet): "name": creator.name, "category": creator.category, "followers": f"{int(creator.followers / 1000)}k" if creator.followers else "0", - "GMV Generated": f"${creator.gmv}k" if creator.gmv else "$0", - "Views Generated": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", + "GMV Achieved": f"${creator.gmv}k" if creator.gmv else "$0", + "Views Achieved": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", "Pricing": f"${creator.pricing}" if creator.pricing else "$0", "Status": cc.status } @@ -554,8 +554,8 @@ class CampaignViewSet(viewsets.ModelViewSet): "creator_name": creator.name, "category": creator.category, "followers": f"{int(creator.followers / 1000)}k" if creator.followers else "0", - "gmv_generated": f"${creator.gmv}k" if creator.gmv else "$0", - "views_generated": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", + "gmv_achieved": f"${creator.gmv}k" if creator.gmv else "$0", + "views_achieved": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", "pricing": f"${creator.pricing}" if creator.pricing else "$0", "status": status } @@ -622,8 +622,8 @@ class CampaignViewSet(viewsets.ModelViewSet): "creator_name": creator.name, "category": creator.category, "followers": f"{int(creator.followers / 1000)}k" if creator.followers else "0", - "gmv_generated": f"${creator.gmv}k" if creator.gmv else "$0", - "views_generated": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", + "gmv_achieved": f"${creator.gmv}k" if creator.gmv else "$0", + "views_achieved": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", "pricing": f"${creator.pricing}" if creator.pricing else "$0", "status": status } @@ -681,8 +681,8 @@ class CampaignViewSet(viewsets.ModelViewSet): "creator_name": creator.name, "category": creator.category, "followers": f"{int(creator.followers / 1000)}k" if creator.followers else "0", - "gmv_generated": f"${creator.gmv}k" if creator.gmv else "$0", - "views_generated": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", + "gmv_achieved": f"${creator.gmv}k" if creator.gmv else "$0", + "views_achieved": f"{int(creator.avg_video_views / 1000)}k" if creator.avg_video_views else "0", "pricing": f"${creator.pricing}" if creator.pricing else "$0", "status": status } diff --git a/apps/daren_detail/daren_detail.md b/apps/daren_detail/daren_detail.md index c6b15c0..c5482aa 100644 --- a/apps/daren_detail/daren_detail.md +++ b/apps/daren_detail/daren_detail.md @@ -78,7 +78,7 @@ Authorization: Token "avatar": "头像URL", "email": "邮箱", "social_user": { - "instagram": "@username", + "instagram": "@name", "tiktok": "tiktok链接" }, "location": "地理位置", @@ -127,7 +127,7 @@ Authorization: Token { "creator_id": 123, // 必填 "email": "新邮箱", - "instagram": "@new_username", + "instagram": "@new_name", "tiktok_link": "新TikTok链接", "location": "新地理位置", "live_schedule": "新直播时间安排", diff --git a/apps/daren_detail/migrations/0008_rename_homepage_link_creatorprofile_tiktok_link.py b/apps/daren_detail/migrations/0008_rename_homepage_link_creatorprofile_tiktok_link.py new file mode 100644 index 0000000..0dd86b1 --- /dev/null +++ b/apps/daren_detail/migrations/0008_rename_homepage_link_creatorprofile_tiktok_link.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.1 on 2025-05-29 02:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('daren_detail', '0007_remove_creatorprofile_tiktok_link_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='creatorprofile', + old_name='homepage_link', + new_name='tiktok_link', + ), + ] diff --git a/apps/discovery/discovery.md b/apps/discovery/discovery.md index 81d75de..b8aacbe 100644 --- a/apps/discovery/discovery.md +++ b/apps/discovery/discovery.md @@ -147,7 +147,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -227,7 +227,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -341,7 +341,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -375,7 +375,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -428,7 +428,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -479,7 +479,7 @@ Authorization: Token your_token_here "items_sold": 500, "avg_video_views": 25000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor", "trends": "summer fitness", "profile": "tiktok" @@ -529,7 +529,7 @@ Authorization: Token your_token_here "items_sold": 800, "avg_video_views": 45000, "has_ecommerce": true, - "tiktok_url": "https://tiktok.com/@username", + "tiktok_url": "https://tiktok.com/@name", "hashtags": "#sport#fitness#outdoor#review", "trends": "fitness equipment review", "profile": "tiktok" diff --git a/apps/feishu/migrations/0001_initial.py b/apps/feishu/migrations/0001_initial.py index 9be10dd..39ecf94 100644 --- a/apps/feishu/migrations/0001_initial.py +++ b/apps/feishu/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.1 on 2025-05-28 08:33 +# Generated by Django 5.2 on 2025-05-07 03:43 import uuid from django.db import migrations, models @@ -46,24 +46,7 @@ class Migration(migrations.Migration): options={ 'verbose_name': '创作者数据', 'verbose_name_plural': '创作者数据', - }, - ), - migrations.CreateModel( - name='FeishuTableMapping', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('app_token', models.CharField(max_length=100, verbose_name='应用令牌')), - ('table_id', models.CharField(max_length=100, verbose_name='表格ID')), - ('table_url', models.TextField(verbose_name='表格URL')), - ('table_name', models.CharField(max_length=100, verbose_name='数据库表名')), - ('feishu_table_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='飞书表格名称')), - ('last_sync_time', models.DateTimeField(auto_now=True, verbose_name='最后同步时间')), - ('total_records', models.IntegerField(default=0, verbose_name='总记录数')), - ], - options={ - 'verbose_name': '飞书表格映射', - 'verbose_name_plural': '飞书表格映射', - 'unique_together': {('app_token', 'table_id')}, + 'db_table': 'feishu_creators', }, ), ] diff --git a/apps/feishu/migrations/0002_feishuauth.py b/apps/feishu/migrations/0002_feishuauth.py new file mode 100644 index 0000000..6764dc7 --- /dev/null +++ b/apps/feishu/migrations/0002_feishuauth.py @@ -0,0 +1,39 @@ +# Generated by Django 5.2 on 2025-05-14 04:30 + +import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('feishu', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='FeishuAuth', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('open_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='飞书Open ID')), + ('union_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='飞书Union ID')), + ('access_token', models.CharField(max_length=512, verbose_name='访问令牌')), + ('refresh_token', models.CharField(max_length=512, verbose_name='刷新令牌')), + ('expires_at', models.DateTimeField(verbose_name='令牌过期时间')), + ('is_active', models.BooleanField(default=True, verbose_name='是否有效')), + ('scopes', models.JSONField(blank=True, default=list, verbose_name='授权范围')), + ('metadata', models.JSONField(blank=True, default=dict, verbose_name='授权元数据')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feishu_auths', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': '飞书授权', + 'verbose_name_plural': '飞书授权', + 'db_table': 'feishu_auths', + }, + ), + ] diff --git a/apps/feishu/migrations/0003_feishutablemapping_delete_feishuauth.py b/apps/feishu/migrations/0003_feishutablemapping_delete_feishuauth.py new file mode 100644 index 0000000..b615c65 --- /dev/null +++ b/apps/feishu/migrations/0003_feishutablemapping_delete_feishuauth.py @@ -0,0 +1,35 @@ +# Generated by Django 5.2 on 2025-05-14 09:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('feishu', '0002_feishuauth'), + ] + + operations = [ + migrations.CreateModel( + name='FeishuTableMapping', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('app_token', models.CharField(max_length=100, verbose_name='应用令牌')), + ('table_id', models.CharField(max_length=100, verbose_name='表格ID')), + ('table_url', models.TextField(verbose_name='表格URL')), + ('table_name', models.CharField(max_length=100, verbose_name='数据库表名')), + ('feishu_table_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='飞书表格名称')), + ('last_sync_time', models.DateTimeField(auto_now=True, verbose_name='最后同步时间')), + ('total_records', models.IntegerField(default=0, verbose_name='总记录数')), + ], + options={ + 'verbose_name': '飞书表格映射', + 'verbose_name_plural': '飞书表格映射', + 'db_table': 'feishu_table_mapping', + 'unique_together': {('app_token', 'table_id')}, + }, + ), + migrations.DeleteModel( + name='FeishuAuth', + ), + ] diff --git a/apps/feishu/migrations/0004_alter_feishucreator_table_and_more.py b/apps/feishu/migrations/0004_alter_feishucreator_table_and_more.py new file mode 100644 index 0000000..1efd34b --- /dev/null +++ b/apps/feishu/migrations/0004_alter_feishucreator_table_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2 on 2025-05-21 04:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('feishu', '0003_feishutablemapping_delete_feishuauth'), + ] + + operations = [ + migrations.AlterModelTable( + name='feishucreator', + table=None, + ), + migrations.AlterModelTable( + name='feishutablemapping', + table=None, + ), + ] diff --git a/apps/feishu/views.py b/apps/feishu/views.py index 8501886..4355396 100644 --- a/apps/feishu/views.py +++ b/apps/feishu/views.py @@ -14,13 +14,13 @@ from .services.data_sync_service import DataSyncService from .services.gmail_extraction_service import GmailExtractionService from .services.auto_gmail_conversation_service import AutoGmailConversationService from rest_framework.permissions import IsAuthenticated -from apps.gmail.models import GmailCredential, GmailConversation, AutoReplyConfig +from apps.gmail.models import GmailCredential, GmailConversation, AutoReplyConfig from apps.gmail.services.gmail_service import GmailService from apps.gmail.serializers import AutoReplyConfigSerializer from apps.gmail.services.goal_service import get_or_create_goal, get_conversation_summary from apps.chat.models import ChatHistory from apps.knowledge_base.models import KnowledgeBase - +from apps.user.authentication import CustomTokenAuthentication logger = logging.getLogger(__name__) @@ -383,6 +383,7 @@ class AutoGmailConversationView(APIView): 自动Gmail对话API,支持自动发送消息并实时接收和回复达人消息 """ permission_classes = [IsAuthenticated] + authentication_classes = [CustomTokenAuthentication] def post(self, request, *args, **kwargs): """ diff --git a/apps/gmail/views.py b/apps/gmail/views.py index 6a857ad..d7a6033 100644 --- a/apps/gmail/views.py +++ b/apps/gmail/views.py @@ -761,9 +761,9 @@ class GmailPubSubView(APIView): credentials = request.user.gmail_credentials.filter(is_valid=True) # 构建响应数据 - accounts = [] + user = [] for cred in credentials: - accounts.append({ + user.append({ 'id': cred.id, 'email': cred.email, 'is_default': cred.is_default @@ -772,7 +772,7 @@ class GmailPubSubView(APIView): return Response({ 'code': 200, 'message': '获取账户列表成功', - 'data': {'accounts': accounts} + 'data': {'user': user} }, status=status.HTTP_200_OK) @@ -915,9 +915,9 @@ class GmailSendEmailView(APIView): credentials = request.user.gmail_credentials.filter(is_valid=True) # 构建响应数据 - accounts = [] + user = [] for cred in credentials: - accounts.append({ + user.append({ 'id': cred.id, 'email': cred.email, 'is_default': cred.is_default @@ -926,7 +926,7 @@ class GmailSendEmailView(APIView): return Response({ 'code': 200, 'message': '获取账户列表成功', - 'data': {'accounts': accounts} + 'data': {'user': user} }, status=status.HTTP_200_OK) diff --git a/apps/user/services/utils.py b/apps/user/services/utils.py index d31e12a..343da31 100644 --- a/apps/user/services/utils.py +++ b/apps/user/services/utils.py @@ -42,7 +42,7 @@ def format_user_response(user, include_is_active=False): """ response = { "id": str(user.id), - "username": user.name, + "name": user.name, "email": user.email, "name": user.name, "role": user.role, diff --git a/daren_detail.md b/daren_detail.md index 0811ade..f331ad8 100644 --- a/daren_detail.md +++ b/daren_detail.md @@ -78,7 +78,7 @@ Authorization: Token "avatar": "头像URL", "email": "邮箱", "social_user": { - "instagram": "@username", + "instagram": "@name", "tiktok": "tiktok链接" }, "location": "地理位置", @@ -127,7 +127,7 @@ Authorization: Token { "creator_id": 123, // 必填 "email": "新邮箱", - "instagram": "@new_username", + "instagram": "@new_name", "tiktok_link": "新TikTok链接", "location": "新地理位置", "live_schedule": "新直播时间安排",