增加飞书模块
This commit is contained in:
parent
93a86d218f
commit
5eab14304c
@ -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
|
||||
}
|
||||
|
@ -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": "新直播时间安排",
|
||||
|
@ -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',
|
||||
),
|
||||
]
|
@ -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"
|
||||
|
@ -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',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
39
apps/feishu/migrations/0002_feishuauth.py
Normal file
39
apps/feishu/migrations/0002_feishuauth.py
Normal 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',
|
||||
},
|
||||
),
|
||||
]
|
@ -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',
|
||||
),
|
||||
]
|
@ -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,
|
||||
),
|
||||
]
|
@ -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):
|
||||
"""
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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": "新直播时间安排",
|
||||
|
Loading…
Reference in New Issue
Block a user