chat_embed_serializers.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # coding=utf-8
  2. """
  3. @project: MaxKB
  4. @Author:虎虎
  5. @file: chat_embed_serializers.py
  6. @date:2025/5/30 14:34
  7. @desc:
  8. """
  9. import os
  10. import uuid_utils.compat as uuid
  11. from django.db.models import QuerySet
  12. from django.http import HttpResponse
  13. from django.template import Template, Context
  14. from django.utils.translation import gettext_lazy as _
  15. from rest_framework import serializers
  16. from application.models import ApplicationAccessToken
  17. from common.database_model_manage.database_model_manage import DatabaseModelManage
  18. from maxkb.conf import PROJECT_DIR
  19. from maxkb.const import CONFIG
  20. class ChatEmbedSerializer(serializers.Serializer):
  21. host = serializers.CharField(required=True, label=_("Host"))
  22. protocol = serializers.CharField(required=True, label=_("protocol"))
  23. token = serializers.CharField(required=True, label=_("token"))
  24. def get_embed(self, with_valid=True, params=None):
  25. if params is None:
  26. params = {}
  27. if with_valid:
  28. self.is_valid(raise_exception=True)
  29. index_path = os.path.join(PROJECT_DIR, 'apps', "chat", 'template', 'embed.js')
  30. file = open(index_path, "r", encoding='utf-8')
  31. content = file.read()
  32. file.close()
  33. application_access_token = QuerySet(ApplicationAccessToken).filter(
  34. access_token=self.data.get('token')).first()
  35. is_draggable = 'false'
  36. show_guide = 'true'
  37. float_icon = f"{self.data.get('protocol')}://{self.data.get('host')}{CONFIG.get_chat_path()}/MaxKB.gif"
  38. is_license_valid = DatabaseModelManage.get_model('license_is_valid')
  39. X_PACK_LICENSE_IS_VALID = is_license_valid() if is_license_valid is not None else False
  40. # 获取接入的query参数
  41. query = self.get_query_api_input(application_access_token.application, params)
  42. float_location = {"x": {"type": "right", "value": 0}, "y": {"type": "bottom", "value": 30}}
  43. header_font_color = "rgb(100, 106, 115)"
  44. application_setting_model = DatabaseModelManage.get_model('application_setting')
  45. if application_setting_model is not None and X_PACK_LICENSE_IS_VALID:
  46. application_setting = QuerySet(application_setting_model).filter(
  47. application_id=application_access_token.application_id).first()
  48. if application_setting is not None:
  49. is_draggable = 'true' if application_setting.draggable else 'false'
  50. if application_setting.float_icon is not None and len(application_setting.float_icon) > 0:
  51. float_icon = application_setting.float_icon[1:] if application_setting.float_icon.startswith(
  52. '.') else application_setting.float_icon
  53. float_icon = f"{self.data.get('protocol')}://{self.data.get('host')}{CONFIG.get_chat_path()}{float_icon}"
  54. show_guide = 'true' if application_setting.show_guide else 'false'
  55. if application_setting.float_location is not None:
  56. float_location = application_setting.float_location
  57. if application_setting.custom_theme is not None and len(
  58. application_setting.custom_theme.get('header_font_color', 'rgb(100, 106, 115)')) > 0:
  59. header_font_color = application_setting.custom_theme.get('header_font_color',
  60. 'rgb(100, 106, 115)')
  61. is_auth = 'true' if application_access_token is not None and application_access_token.is_active else 'false'
  62. t = Template(content)
  63. s = t.render(
  64. Context(
  65. {'is_auth': is_auth, 'protocol': self.data.get('protocol'), 'host': self.data.get('host'),
  66. 'token': self.data.get('token'),
  67. 'white_list_str': ",".join(
  68. application_access_token.white_list if application_access_token.white_list is not None else []),
  69. 'white_active': 'true' if application_access_token.white_active else 'false',
  70. 'is_draggable': is_draggable,
  71. 'float_icon': float_icon,
  72. 'prefix': CONFIG.get_chat_path(),
  73. 'query': query,
  74. 'show_guide': show_guide,
  75. 'x_type': float_location.get('x', {}).get('type', 'right'),
  76. 'x_value': float_location.get('x', {}).get('value', 0),
  77. 'y_type': float_location.get('y', {}).get('type', 'bottom'),
  78. 'y_value': float_location.get('y', {}).get('value', 30),
  79. 'max_kb_id': str(uuid.uuid7()).replace('-', ''),
  80. 'header_font_color': header_font_color}))
  81. response = HttpResponse(s, status=200, headers={'Content-Type': 'text/javascript'})
  82. return response
  83. @staticmethod
  84. def get_query_api_input(application, params):
  85. query = ''
  86. if application.work_flow is not None:
  87. work_flow = application.work_flow
  88. if work_flow is not None:
  89. for node in work_flow.get('nodes', []):
  90. if node['id'] == 'base-node':
  91. input_field_list = node.get('properties', {}).get('api_input_field_list',
  92. node.get('properties', {}).get(
  93. 'input_field_list', []))
  94. if input_field_list is not None:
  95. for field in input_field_list:
  96. if field['assignment_method'] == 'api_input' and field['variable'] in params:
  97. query += f"&{field['variable']}={params[field['variable']]}"
  98. if 'asker' in params:
  99. query += f"&asker={params.get('asker')}"
  100. return query