增加飞书模块

This commit is contained in:
wanjia 2025-05-29 16:11:38 +08:00
parent 93a86d218f
commit 5eab14304c
12 changed files with 144 additions and 47 deletions

View File

@ -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
}

View File

@ -78,7 +78,7 @@ Authorization: Token <your_token>
"avatar": "头像URL",
"email": "邮箱",
"social_user": {
"instagram": "@username",
"instagram": "@name",
"tiktok": "tiktok链接"
},
"location": "地理位置",
@ -127,7 +127,7 @@ Authorization: Token <your_token>
{
"creator_id": 123, // 必填
"email": "新邮箱",
"instagram": "@new_username",
"instagram": "@new_name",
"tiktok_link": "新TikTok链接",
"location": "新地理位置",
"live_schedule": "新直播时间安排",

View File

@ -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',
),
]

View File

@ -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"

View File

@ -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',
},
),
]

View File

@ -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',
},
),
]

View File

@ -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',
),
]

View File

@ -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,
),
]

View File

@ -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):
"""

View File

@ -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)

View File

@ -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,

View File

@ -78,7 +78,7 @@ Authorization: Token <your_token>
"avatar": "头像URL",
"email": "邮箱",
"social_user": {
"instagram": "@username",
"instagram": "@name",
"tiktok": "tiktok链接"
},
"location": "地理位置",
@ -127,7 +127,7 @@ Authorization: Token <your_token>
{
"creator_id": 123, // 必填
"email": "新邮箱",
"instagram": "@new_username",
"instagram": "@new_name",
"tiktok_link": "新TikTok链接",
"location": "新地理位置",
"live_schedule": "新直播时间安排",