From c31ddcf45374d55efac2d7485dd2c1b095b7a544 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 May 2025 16:12:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E6=88=90platforms=E4=B8=8B=E9=9D=A2?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E5=A4=9A=E4=B8=AA=E6=95=B0=E7=BB=84=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._2543b088-119e-4ab6-951e-c21539cb500e.json | 1 + ..._76329a35-a3c8-4448-976b-107a35578dee.json | 1 + ..._a4947680-9727-41f4-8581-4c3853e14252.json | 1 + ..._aa8b61e7-d823-40d5-9338-a4d7568b919d.json | 1 + ..._b86128e7-46f4-4769-950a-afce519317f4.json | 1 + operation/serializers.py | 45 ++++ operation/views.py | 224 +++++++++++------- requirements.txt | Bin 4478 -> 988 bytes role_based_system/settings.py | 2 +- user_management/models.py | 4 +- 10 files changed, 186 insertions(+), 94 deletions(-) create mode 100644 gmail_tokens/gmail_token_2543b088-119e-4ab6-951e-c21539cb500e.json create mode 100644 gmail_tokens/gmail_token_76329a35-a3c8-4448-976b-107a35578dee.json create mode 100644 gmail_tokens/gmail_token_a4947680-9727-41f4-8581-4c3853e14252.json create mode 100644 gmail_tokens/gmail_token_aa8b61e7-d823-40d5-9338-a4d7568b919d.json create mode 100644 gmail_tokens/gmail_token_b86128e7-46f4-4769-950a-afce519317f4.json diff --git a/gmail_tokens/gmail_token_2543b088-119e-4ab6-951e-c21539cb500e.json b/gmail_tokens/gmail_token_2543b088-119e-4ab6-951e-c21539cb500e.json new file mode 100644 index 0000000..40e0d9b --- /dev/null +++ b/gmail_tokens/gmail_token_2543b088-119e-4ab6-951e-c21539cb500e.json @@ -0,0 +1 @@ +{"access_token": "ya29.a0AZYkNZjZEySq85J9PqCmBveB4t7CNcPjaau9kjbTpoKuM6S26K3Vf8Fw4XaUUDaMAx6kdDVb8k-ORr42azXJBFwXTB-oSl-nZyifqcFieyZ6S0Hp3BRNFp8MseAq8b233X3avTY4Urwf_ldi3TDfoUXKDm_3HcVGauTMaosLaCgYKAUMSARYSFQHGX2MiKrB2GNWWfYpqWutcP1Y7QQ0175", "client_id": "266164728215-v84lngbp3vgr4ulql01sqkg5vaigf4a5.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//0ejXTvHJvjMeBCgYIARAAGA4SNwF-L9IrzYy7RkmUVbVmBryxvFPPpZCAsQ_Y6EZMIlCWAtw9JpNz__WWJ8i4-hlGNMOQ23nYKxY", "token_expiry": "2025-04-18T03:26:24Z", "token_uri": "https://oauth2.googleapis.com/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.a0AZYkNZjZEySq85J9PqCmBveB4t7CNcPjaau9kjbTpoKuM6S26K3Vf8Fw4XaUUDaMAx6kdDVb8k-ORr42azXJBFwXTB-oSl-nZyifqcFieyZ6S0Hp3BRNFp8MseAq8b233X3avTY4Urwf_ldi3TDfoUXKDm_3HcVGauTMaosLaCgYKAUMSARYSFQHGX2MiKrB2GNWWfYpqWutcP1Y7QQ0175", "expires_in": 3599, "refresh_token": "1//0ejXTvHJvjMeBCgYIARAAGA4SNwF-L9IrzYy7RkmUVbVmBryxvFPPpZCAsQ_Y6EZMIlCWAtw9JpNz__WWJ8i4-hlGNMOQ23nYKxY", "scope": "https://mail.google.com/", "token_type": "Bearer"}, "scopes": ["https://mail.google.com/"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"} \ No newline at end of file diff --git a/gmail_tokens/gmail_token_76329a35-a3c8-4448-976b-107a35578dee.json b/gmail_tokens/gmail_token_76329a35-a3c8-4448-976b-107a35578dee.json new file mode 100644 index 0000000..445b625 --- /dev/null +++ b/gmail_tokens/gmail_token_76329a35-a3c8-4448-976b-107a35578dee.json @@ -0,0 +1 @@ +{"access_token": "ya29.a0AZYkNZjPu9urXFL2BpwCTRUm2hhJPByTSIk6K6RHi8rRXHfHU5sHgjM7dmx_fBX58sWdNxgZ8icLSr8M2aEd9uGvDdUPTL_M5pBjbMxZV3mAKmaAm4ba1ljHffRgdfST261ZWEWx-TJqy2yFnY-KwtqycKAyPIqXA9KEX8xbaCgYKAdwSARYSFQHGX2MiXTJWkL8BJwG4B3-ZSN7tTQ0175", "client_id": "266164728215-v84lngbp3vgr4ulql01sqkg5vaigf4a5.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//0ee088frn4Y6ACgYIARAAGA4SNwF-L9IrTy0HIk27CSbkrNEJud15D3p8pXmJ1jrXWyt-XVTLFO95C0oHAxFgYOXhKvqAdHQP9R0", "token_expiry": "2025-04-17T10:13:16Z", "token_uri": "https://oauth2.googleapis.com/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.a0AZYkNZjPu9urXFL2BpwCTRUm2hhJPByTSIk6K6RHi8rRXHfHU5sHgjM7dmx_fBX58sWdNxgZ8icLSr8M2aEd9uGvDdUPTL_M5pBjbMxZV3mAKmaAm4ba1ljHffRgdfST261ZWEWx-TJqy2yFnY-KwtqycKAyPIqXA9KEX8xbaCgYKAdwSARYSFQHGX2MiXTJWkL8BJwG4B3-ZSN7tTQ0175", "expires_in": 3599, "refresh_token": "1//0ee088frn4Y6ACgYIARAAGA4SNwF-L9IrTy0HIk27CSbkrNEJud15D3p8pXmJ1jrXWyt-XVTLFO95C0oHAxFgYOXhKvqAdHQP9R0", "scope": "https://mail.google.com/", "token_type": "Bearer"}, "scopes": ["https://mail.google.com/"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"} \ No newline at end of file diff --git a/gmail_tokens/gmail_token_a4947680-9727-41f4-8581-4c3853e14252.json b/gmail_tokens/gmail_token_a4947680-9727-41f4-8581-4c3853e14252.json new file mode 100644 index 0000000..2431f32 --- /dev/null +++ b/gmail_tokens/gmail_token_a4947680-9727-41f4-8581-4c3853e14252.json @@ -0,0 +1 @@ +{"access_token": "ya29.a0AZYkNZjp_7lmkLRZwUuCrZCQ__VwQjaLKwnJ8jSlDdPSAAHoTa-tjicTUA56u7Ves4bTq8uPXSVdtUc0x4P2FX_I7UxYub1OaXaOgHtkJp_un2hcnJHzTML1pQAt6i_-Ad-jy76H1KZhpCMyjdgn3yLoRKiyoP6DRXiwqFC4aCgYKATMSARYSFQHGX2MiJrlvAasq3_xPnyc8lEFksw0175", "client_id": "266164728215-v84lngbp3vgr4ulql01sqkg5vaigf4a5.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//05wdEUZe8ecbqCgYIARAAGAUSNwF-L9IrPa38Ovemb7suLLJAcd_LpeWObYpAvfeaquygg0qH0O7Gktad2iM8dAEMgpL3aC3Bpzo", "token_expiry": "2025-04-21T04:24:12Z", "token_uri": "https://oauth2.googleapis.com/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.a0AZYkNZjp_7lmkLRZwUuCrZCQ__VwQjaLKwnJ8jSlDdPSAAHoTa-tjicTUA56u7Ves4bTq8uPXSVdtUc0x4P2FX_I7UxYub1OaXaOgHtkJp_un2hcnJHzTML1pQAt6i_-Ad-jy76H1KZhpCMyjdgn3yLoRKiyoP6DRXiwqFC4aCgYKATMSARYSFQHGX2MiJrlvAasq3_xPnyc8lEFksw0175", "expires_in": 3599, "refresh_token": "1//05wdEUZe8ecbqCgYIARAAGAUSNwF-L9IrPa38Ovemb7suLLJAcd_LpeWObYpAvfeaquygg0qH0O7Gktad2iM8dAEMgpL3aC3Bpzo", "scope": "https://mail.google.com/", "token_type": "Bearer"}, "scopes": ["https://mail.google.com/"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"} \ No newline at end of file diff --git a/gmail_tokens/gmail_token_aa8b61e7-d823-40d5-9338-a4d7568b919d.json b/gmail_tokens/gmail_token_aa8b61e7-d823-40d5-9338-a4d7568b919d.json new file mode 100644 index 0000000..a571c6c --- /dev/null +++ b/gmail_tokens/gmail_token_aa8b61e7-d823-40d5-9338-a4d7568b919d.json @@ -0,0 +1 @@ +{"access_token": "ya29.a0AZYkNZhi8J3ScCuEF-nw7cTZRv3vKa-AR45285jhNNVRGJ866yUk2aZ2n3_rWElUGk-TAc1-OL2IOcabMj_HX_Qa_fBvh4FeowRrJ4msUwpXdmBK8Bwd_hlRwuBfU41KugIC6jBkmahi7xaSU2jOz_hQ7v8W-XknxUNHQZy5aCgYKAW4SARYSFQHGX2MijjVj6C9CPrb9k6sG2uw4gQ0175", "client_id": "266164728215-v84lngbp3vgr4ulql01sqkg5vaigf4a5.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//0eq_h4As72k1nCgYIARAAGA4SNwF-L9Iri7yzjjFKV6QLIiASrfp5_rIRV6vRSI3AJq8c_62aKlIK_D-31_CxfxNCAUAtsLqLiTA", "token_expiry": "2025-04-21T04:14:40Z", "token_uri": "https://oauth2.googleapis.com/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.a0AZYkNZhi8J3ScCuEF-nw7cTZRv3vKa-AR45285jhNNVRGJ866yUk2aZ2n3_rWElUGk-TAc1-OL2IOcabMj_HX_Qa_fBvh4FeowRrJ4msUwpXdmBK8Bwd_hlRwuBfU41KugIC6jBkmahi7xaSU2jOz_hQ7v8W-XknxUNHQZy5aCgYKAW4SARYSFQHGX2MijjVj6C9CPrb9k6sG2uw4gQ0175", "expires_in": 3599, "refresh_token": "1//0eq_h4As72k1nCgYIARAAGA4SNwF-L9Iri7yzjjFKV6QLIiASrfp5_rIRV6vRSI3AJq8c_62aKlIK_D-31_CxfxNCAUAtsLqLiTA", "scope": "https://mail.google.com/", "token_type": "Bearer"}, "scopes": ["https://mail.google.com/"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"} \ No newline at end of file diff --git a/gmail_tokens/gmail_token_b86128e7-46f4-4769-950a-afce519317f4.json b/gmail_tokens/gmail_token_b86128e7-46f4-4769-950a-afce519317f4.json new file mode 100644 index 0000000..42a7ff0 --- /dev/null +++ b/gmail_tokens/gmail_token_b86128e7-46f4-4769-950a-afce519317f4.json @@ -0,0 +1 @@ +{"access_token": "ya29.a0AZYkNZgkU6sFdked-sQ8ukavnNRdRkyNLOGC-AqHWb3-rqHcIWsSDx2KYKyODqTfB-CvB_EzREC5HFKuWesr-_4yjAclzhASo-7PfCxQ4FZgBSixbd9rtYSuFVvEFrT8_WJ4Q5i9WEJ4VS0qa1q71Bn2y-SXk1gSQNxHggX3aCgYKAcASARISFQHGX2MiYvEgHyrZ4ZiRk0eLRRoJEQ0175", "client_id": "266164728215-v84lngbp3vgr4ulql01sqkg5vaigf4a5.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//0eOdh14jvZOfnCgYIARAAGA4SNwF-L9Ir7ATFfGLbwThkDzJhkLLO9eBCmQF5Djgx1kdVguyGUcNbLqApznUA4ANgLhCJ92yUAGw", "token_expiry": "2025-04-17T22:45:44Z", "token_uri": "https://oauth2.googleapis.com/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.a0AZYkNZgkU6sFdked-sQ8ukavnNRdRkyNLOGC-AqHWb3-rqHcIWsSDx2KYKyODqTfB-CvB_EzREC5HFKuWesr-_4yjAclzhASo-7PfCxQ4FZgBSixbd9rtYSuFVvEFrT8_WJ4Q5i9WEJ4VS0qa1q71Bn2y-SXk1gSQNxHggX3aCgYKAcASARISFQHGX2MiYvEgHyrZ4ZiRk0eLRRoJEQ0175", "expires_in": 3599, "refresh_token": "1//0eOdh14jvZOfnCgYIARAAGA4SNwF-L9Ir7ATFfGLbwThkDzJhkLLO9eBCmQF5Djgx1kdVguyGUcNbLqApznUA4ANgLhCJ92yUAGw", "scope": "https://mail.google.com/", "token_type": "Bearer", "refresh_token_expires_in": 604799}, "scopes": ["https://mail.google.com/"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"} \ No newline at end of file diff --git a/operation/serializers.py b/operation/serializers.py index bef24ac..4407d0f 100644 --- a/operation/serializers.py +++ b/operation/serializers.py @@ -1,6 +1,7 @@ from rest_framework import serializers from user_management.models import OperatorAccount, PlatformAccount, Video, KnowledgeBase, KnowledgeBaseDocument import uuid +from django.db.models import Q class OperatorAccountSerializer(serializers.ModelSerializer): @@ -55,6 +56,50 @@ class PlatformAccountSerializer(serializers.ModelSerializer): return super().to_internal_value(data) +class PlatformDetailSerializer(serializers.Serializer): + """平台详情序列化器,用于多平台账号创建""" + platform_name = serializers.ChoiceField(choices=PlatformAccount.PLATFORM_CHOICES) + platform_url = serializers.URLField() + + +class MultiPlatformAccountSerializer(serializers.Serializer): + """多平台账号创建序列化器""" + operator = serializers.PrimaryKeyRelatedField(queryset=OperatorAccount.objects.all()) + account_name = serializers.CharField(max_length=100) + account_id = serializers.CharField(max_length=100) + status = serializers.ChoiceField(choices=PlatformAccount.STATUS_CHOICES, default='active') + followers_count = serializers.IntegerField(default=0) + description = serializers.CharField(required=False, allow_blank=True, allow_null=True) + tags = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=255) + profile_image = serializers.URLField(required=False, allow_blank=True, allow_null=True) + last_posting = serializers.DateTimeField(required=False, allow_null=True) + platforms = PlatformDetailSerializer(many=True) + + def to_internal_value(self, data): + # 处理operator字段,可能是字符串类型的ID + if 'operator' in data and isinstance(data['operator'], str): + try: + # 尝试通过ID查找运营账号 + operator_id = data['operator'] + try: + # 先尝试通过整数ID查找 + operator_id_int = int(operator_id) + operator = OperatorAccount.objects.get(id=operator_id_int) + data['operator'] = operator.id + except (ValueError, OperatorAccount.DoesNotExist): + # 如果无法转换为整数或找不到对应账号,尝试通过用户名或真实姓名查找 + operator = OperatorAccount.objects.filter( + Q(username=operator_id) | Q(real_name=operator_id) + ).first() + + if operator: + data['operator'] = operator.id + except Exception as e: + pass + + return super().to_internal_value(data) + + class VideoSerializer(serializers.ModelSerializer): platform_account_name = serializers.CharField(source='platform_account.account_name', read_only=True) platform_name = serializers.CharField(source='platform_account.platform_name', read_only=True) diff --git a/operation/views.py b/operation/views.py index e17d2f7..655cd12 100644 --- a/operation/views.py +++ b/operation/views.py @@ -16,7 +16,7 @@ import os from user_management.models import OperatorAccount, PlatformAccount, Video, KnowledgeBase, KnowledgeBaseDocument, User from .serializers import ( OperatorAccountSerializer, PlatformAccountSerializer, VideoSerializer, - KnowledgeBaseSerializer, KnowledgeBaseDocumentSerializer + KnowledgeBaseSerializer, KnowledgeBaseDocumentSerializer, MultiPlatformAccountSerializer ) from .pagination import CustomPagination @@ -245,102 +245,144 @@ class PlatformAccountViewSet(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): """创建平台账号并记录到知识库""" - with transaction.atomic(): - # 处理operator字段,可能是字符串类型的ID - data = request.data.copy() - if 'operator' in data and isinstance(data['operator'], str): - try: - # 尝试通过ID查找运营账号 - operator_id = data['operator'] - try: - # 先尝试通过整数ID查找 - operator_id_int = int(operator_id) - operator = OperatorAccount.objects.get(id=operator_id_int) - except (ValueError, OperatorAccount.DoesNotExist): - # 如果无法转换为整数或找不到对应账号,尝试通过用户名或真实姓名查找 - operator = OperatorAccount.objects.filter( - Q(username=operator_id) | Q(real_name=operator_id) - ).first() - - if not operator: - return Response({ - "code": 404, - "message": f"未找到运营账号: {operator_id},请提供有效的ID、用户名或真实姓名", - "data": None - }, status=status.HTTP_404_NOT_FOUND) - - # 更新请求数据中的operator字段为找到的operator的ID - data['operator'] = operator.id - - except Exception as e: - return Response({ - "code": 400, - "message": f"处理运营账号ID时出错: {str(e)}", - "data": None - }, status=status.HTTP_400_BAD_REQUEST) - - # 创建平台账号 - serializer = self.get_serializer(data=data) + # 检查请求数据中是否包含platforms字段,判断是否为多平台账号创建 + if 'platforms' in request.data and isinstance(request.data['platforms'], list): + # 使用多平台账号序列化器 + serializer = MultiPlatformAccountSerializer(data=request.data) serializer.is_valid(raise_exception=True) - # 手动创建平台账号,不使用serializer.save()避免ID问题 - platform_data = serializer.validated_data - platform_account = PlatformAccount.objects.create(**platform_data) + created_accounts = [] - # 获取关联的运营账号 - operator = platform_account.operator - - # 查找对应的知识库 - knowledge_base = KnowledgeBase.objects.filter( - name__contains=operator.real_name, - type='private' - ).first() - - if knowledge_base and knowledge_base.external_id: - # 创建平台账号文档 - document_data = { - "name": f"{platform_account.account_name}_{platform_account.platform_name}_账号信息", - "paragraphs": [ - { - "title": "平台账号基本信息", - "content": f""" - 平台: {platform_account.get_platform_name_display()} - 账号名称: {platform_account.account_name} - 账号ID: {platform_account.account_id} - 账号状态: {platform_account.get_status_display()} - 粉丝数: {platform_account.followers_count} - 账号链接: {platform_account.account_url} - 账号描述: {platform_account.description or '无'} - 标签: {platform_account.tags or '无'} - 头像链接: {platform_account.profile_image or '无'} - 最后发布时间: {platform_account.last_posting.strftime('%Y-%m-%d %H:%M:%S') if platform_account.last_posting else '未发布'} - 创建时间: {platform_account.created_at.strftime('%Y-%m-%d %H:%M:%S')} - 最后登录: {platform_account.last_login.strftime('%Y-%m-%d %H:%M:%S') if platform_account.last_login else '从未登录'} - """, - "is_active": True - } - ] - } + with transaction.atomic(): + # 获取基础账号信息 + base_data = serializer.validated_data.copy() + platforms_data = base_data.pop('platforms') + operator = base_data['operator'] - # 调用外部API创建文档 - document_id = self._create_document(knowledge_base.external_id, document_data) + # 遍历平台数据创建多个平台账号 + for platform_data in platforms_data: + # 创建平台账号数据 + platform_account_data = base_data.copy() + platform_account_data['platform_name'] = platform_data['platform_name'] + platform_account_data['account_url'] = platform_data['platform_url'] + + # 创建平台账号 + platform_account = PlatformAccount.objects.create(**platform_account_data) + created_accounts.append(platform_account) + + # 记录到知识库 + self._add_to_knowledge_base(platform_account, request.user) - if document_id: - # 创建知识库文档记录 - KnowledgeBaseDocument.objects.create( - knowledge_base=knowledge_base, - document_id=document_id, - document_name=document_data["name"], - external_id=document_id, - uploader_name=request.user.username - ) + # 将创建的账号序列化返回 + result_serializer = self.get_serializer(created_accounts, many=True) + return Response({ + "code": 200, + "message": "多平台账号创建成功,并已添加到知识库", + "data": result_serializer.data + }, status=status.HTTP_201_CREATED) + else: + # 传统单平台账号创建流程 + with transaction.atomic(): + # 处理operator字段,可能是字符串类型的ID + data = request.data.copy() + if 'operator' in data and isinstance(data['operator'], str): + try: + # 尝试通过ID查找运营账号 + operator_id = data['operator'] + try: + # 先尝试通过整数ID查找 + operator_id_int = int(operator_id) + operator = OperatorAccount.objects.get(id=operator_id_int) + except (ValueError, OperatorAccount.DoesNotExist): + # 如果无法转换为整数或找不到对应账号,尝试通过用户名或真实姓名查找 + operator = OperatorAccount.objects.filter( + Q(username=operator_id) | Q(real_name=operator_id) + ).first() + + if not operator: + return Response({ + "code": 404, + "message": f"未找到运营账号: {operator_id},请提供有效的ID、用户名或真实姓名", + "data": None + }, status=status.HTTP_404_NOT_FOUND) + + # 更新请求数据中的operator字段为找到的operator的ID + data['operator'] = operator.id + + except Exception as e: + return Response({ + "code": 400, + "message": f"处理运营账号ID时出错: {str(e)}", + "data": None + }, status=status.HTTP_400_BAD_REQUEST) + + # 创建平台账号 + serializer = self.get_serializer(data=data) + serializer.is_valid(raise_exception=True) + + # 手动创建平台账号,不使用serializer.save()避免ID问题 + platform_data = serializer.validated_data + platform_account = PlatformAccount.objects.create(**platform_data) + + # 记录到知识库 + self._add_to_knowledge_base(platform_account, request.user) + + return Response({ + "code": 200, + "message": "平台账号创建成功,并已添加到知识库", + "data": self.get_serializer(platform_account).data + }, status=status.HTTP_201_CREATED) + + def _add_to_knowledge_base(self, platform_account, user): + """将平台账号添加到知识库""" + # 获取关联的运营账号 + operator = platform_account.operator + + # 查找对应的知识库 + knowledge_base = KnowledgeBase.objects.filter( + name__contains=operator.real_name, + type='private' + ).first() + + if knowledge_base and knowledge_base.external_id: + # 创建平台账号文档 + document_data = { + "name": f"{platform_account.account_name}_{platform_account.platform_name}_账号信息", + "paragraphs": [ + { + "title": "平台账号基本信息", + "content": f""" + 平台: {platform_account.get_platform_name_display()} + 账号名称: {platform_account.account_name} + 账号ID: {platform_account.account_id} + 账号状态: {platform_account.get_status_display()} + 粉丝数: {platform_account.followers_count} + 账号链接: {platform_account.account_url} + 账号描述: {platform_account.description or '无'} + 标签: {platform_account.tags or '无'} + 头像链接: {platform_account.profile_image or '无'} + 最后发布时间: {platform_account.last_posting.strftime('%Y-%m-%d %H:%M:%S') if platform_account.last_posting else '未发布'} + 创建时间: {platform_account.created_at.strftime('%Y-%m-%d %H:%M:%S')} + 最后登录: {platform_account.last_login.strftime('%Y-%m-%d %H:%M:%S') if platform_account.last_login else '从未登录'} + """, + "is_active": True + } + ] + } - return Response({ - "code": 200, - "message": "平台账号创建成功,并已添加到知识库", - "data": self.get_serializer(platform_account).data - }, status=status.HTTP_201_CREATED) - + # 调用外部API创建文档 + document_id = self._create_document(knowledge_base.external_id, document_data) + + if document_id: + # 创建知识库文档记录 + KnowledgeBaseDocument.objects.create( + knowledge_base=knowledge_base, + document_id=document_id, + document_name=document_data["name"], + external_id=document_id, + uploader_name=user.username + ) + def destroy(self, request, *args, **kwargs): """删除平台账号并更新相关知识库文档""" platform_account = self.get_object() diff --git a/requirements.txt b/requirements.txt index 54f036d735a9da2347957d2cbce1b2b3e9d79086..6b6820fba6bf1097ded81c9fbca49a9d93ff29e4 100644 GIT binary patch literal 988 zcmZ`%%Syvg6r6RwLU3!ei3%=MD7X^C%K-NqXnZ%$ak3e>?;T@cH=lrEuqbykA@QIjf9`Rtf zEOwN6unR~V9oBeB7cOgzcdMi%D(Ou`g$bR9?8+v$RQo!KfDXi$@Eq{C%+10kHt;=q zYg`l60ootUuW4LgUR=Etok{jFxo)ZL>3nB;BKNCYoFwOBopdCVi|MAXyXo;)zRP*% zbNFAa%}SYXr1KnLmZX!PYSvZctL~zebu?l+F~+Rz@&t6El6pxcooo|zoS~{w;#sQF zKgBk@h6}UdEU2WdGOQeBR9J&zDcH z?~O&v?8%tZH?uRDOQ){hfC}ed-j`7Ci^5dv=QV2dG~^R9bMfXR>f%Cpq+i*$OeJ-v O=s+fBQWQ>imBJs;Wv#vd literal 4478 zcma)gw*9fBv47WogP?nUu9Y`!bL3jsE|j&$fK8&#;`8vA%=S)9=>bm7VmFjzThs zKQB6sjV#TiYYRxNmln2?Ey^nVU?nw%VPPdnBM%dOvD4Szd-x<5q978o`4~1E*(aMS&p2-6cM>{FMfnt{6USOsGNVDDHm%ssp0y8DcIm)qHI>Olq{fr;C}grydN0XdZSDJ)fVUx zb6++aX@katqI->4$@BOOnV~lcP2~8-<~aN}va^*vqTES$-{xtSS(iLE!5b>H2y1I) zX5EXhh9-5K$r3U$&S;QJ%|A zT3K=lRA&dWzPyn?eyH|DQmX2H0*B=P;VGDo=iA5?Mn8v@`!1(J$CCed?ppTfjkR*0 zE52u0Ctuhov-e=-IOf?~KI!JWh#z00LYKa;M{PU_@p7Zsk_(*vuXBy^ zvoD`aEZm*Pxfuzg%N%)Zb6W?);C7v|<6xT6fepr+&clPd!+m)t90pyyOaw=Kr%aBg zcb+1j%-8I6RXhvL{gi);M*US6tK z*eo?;PA>Hu^I$Ig%m*eAI%X981a4oX$=2C)@n!F3zprI`CtKzT*^l($r02m}6~SAz z0)iPGGlc&4j75(akfKE3C$+K@wGU5T(l_F+F=N5FN?D#ro zhRTHMnEUuKo}hQASLcy2b61@5g7~gFJjf&2k7d_`{F$}A4(W+dhw%&PWZ%InDzOsU zY*$O10g&b6bEwQSKax_LjPD|m_U(x~@gPY9y%TZid6S5%c}VEC#0F6=)lGrxJ5q*-^JeI^m1jQG43jg=XV`Qfx!ng6c))t@eX?fTKJd zNIq-t_?FB2)iHYlxH_DDQDqX7VLLOKY{=*g_XHJUyUWy3Oa%o)Ew z(gsr#E7&$`m_u~_t1u_yv&f!UHu27YvuNiGdX-(j0-1!H7HjMqQDWf?vzVFsgU;rS p0omazi0xc8`_WV6&KZ#N>~d%Ot&0R?Q*t_Wj9kvEv_p>I{4e2GwHW{a diff --git a/role_based_system/settings.py b/role_based_system/settings.py index 91c0862..7e4c0a8 100644 --- a/role_based_system/settings.py +++ b/role_based_system/settings.py @@ -105,7 +105,7 @@ DATABASES = { 'NAME': 'rolebasedfilemanagement', 'USER': 'root', 'PASSWORD': '123456', - 'HOST': '127.0.0.1', + 'HOST': 'localhost', # 使用本地MySQL 'PORT': '3306', 'OPTIONS': { 'charset': 'utf8mb4', # 使用 utf8mb4 字符集 diff --git a/user_management/models.py b/user_management/models.py index fe91e66..1fa59a9 100644 --- a/user_management/models.py +++ b/user_management/models.py @@ -869,12 +869,12 @@ class PlatformAccount(models.Model): account_id = models.CharField(max_length=100, verbose_name='账号ID') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name='账号状态') followers_count = models.IntegerField(default=0, verbose_name='粉丝数') - account_url = models.URLField(verbose_name='账号链接') + account_url = models.URLField(blank=True, null=True, verbose_name='账号链接') description = models.TextField(blank=True, null=True, verbose_name='账号描述') # 新增字段 tags = models.CharField(max_length=255, blank=True, null=True, verbose_name='标签', help_text='用逗号分隔的标签列表') - profile_image = models.URLField(blank=True, null=True, verbose_name='头像URL') + profile_image = models.URLField(blank=True, null=True, verbose_name='账号头像') last_posting = models.DateTimeField(blank=True, null=True, verbose_name='最后发布时间') created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')