1919import requests
2020import uuid_utils .compat as uuid
2121from django .db import transaction
22- from django .db .models import QuerySet
22+ from django .db .models import QuerySet , Q
2323from django .http import HttpResponse
2424from django .utils import timezone
2525from django .utils .translation import gettext_lazy as _
2626from rest_framework import serializers , status
27+ from rest_framework .utils .formatting import lazy_format
2728
2829from application .flow .common import Workflow , WorkflowMode
2930from application .flow .i_step_node import ToolWorkflowPostHandler
3031from application .flow .tool_workflow_manage import ToolWorkflowManage
3132from application .models import ChatRecord
3233from application .serializers .application import McpServersSerializer , get_mcp_tools
3334from application .serializers .common import ToolExecute
35+ from common .database_model_manage .database_model_manage import DatabaseModelManage
3436from common .exception .app_exception import AppApiException
3537from common .field .common import UploadedFileField
3638from common .result import result
3739from common .utils .common import bytes_to_uploaded_file
3840from common .utils .common import restricted_loads , generate_uuid
3941from common .utils .logger import maxkb_logger
4042from common .utils .tool_code import ToolExecutor
41- from knowledge .models import KnowledgeWorkflow
43+ from knowledge .models import KnowledgeWorkflow , Knowledge , KnowledgeScope
44+ from knowledge .serializers .knowledge import KnowledgeModelSerializer , KnowledgeSerializer
4245from system_manage .models import AuthTargetType
46+ from system_manage .models .resource_mapping import ResourceMapping
4347from system_manage .serializers .user_resource_permission import UserResourcePermissionSerializer
4448from tools .models import Tool , ToolScope , ToolWorkflow , ToolWorkflowVersion
4549from tools .serializers .tool import ToolExportModelSerializer , ToolSerializer
@@ -173,6 +177,54 @@ def publish(self, with_valid=True):
173177 ).update (is_publish = True , publish_time = timezone .now ())
174178 return True
175179
180+ def list_knowledge (self , with_valid = True ):
181+ if with_valid :
182+ self .is_valid (raise_exception = True )
183+ workspace_id = self .data .get ("workspace_id" )
184+ user_id = self .data .get ('user_id' )
185+ knowledge_workspace_authorization_model = DatabaseModelManage .get_model ('knowledge_workspace_authorization' )
186+ share_knowledge_list = []
187+ if knowledge_workspace_authorization_model is not None :
188+ white_list_condition = Q (authentication_type = 'WHITE_LIST' ) & Q (
189+ workspace_id_list__contains = [workspace_id ])
190+ default_condition = ~ Q (authentication_type = 'WHITE_LIST' ) & ~ Q (
191+ workspace_id_list__contains = [workspace_id ])
192+ # 组合查询
193+ query = white_list_condition | default_condition
194+ inner = QuerySet (knowledge_workspace_authorization_model ).filter (query )
195+ share_knowledge_list = [{** KnowledgeModelSerializer (k ).data , 'scope' : 'SHARED' } for k in
196+ QuerySet (Knowledge ).filter (id__in = inner )]
197+ workspace_knowledge_list = [{** k , 'scope' : 'WORKSPACE' } for k in KnowledgeSerializer .Query (
198+ data = {
199+ 'workspace_id' : workspace_id ,
200+ 'scope' : KnowledgeScope .WORKSPACE ,
201+ 'user_id' : user_id
202+ }
203+ ).list () if k .get ('resource_type' ) == 'knowledge' ]
204+
205+ return [* workspace_knowledge_list , * share_knowledge_list ]
206+
207+ @staticmethod
208+ def get_tool_knowledge_mapping (application_knowledge_id_list , knowledge_id_list , tool_id ):
209+ """
210+
211+ @param application_knowledge_id_list: 当前应用可修改的知识库列表
212+ @param knowledge_id_list: 用户修改的知识库列表
213+ @param application_id: 应用id
214+ @return:
215+ """
216+ # 当前知识库和应用已关联列表
217+ knowledge_application_mapping_list = QuerySet (ResourceMapping ).filter (source_id = tool_id ,
218+ source_type = 'TOOL' ,
219+ target_type = "KNOWLEDGE" ,
220+ ).exclude (
221+ target_id__in = application_knowledge_id_list )
222+ edit_knowledge_list = [ResourceMapping (source_id = tool_id , target_id = knowledge_id ,
223+ source_type = 'TOOL' ,
224+ target_type = "KNOWLEDGE" )
225+ for knowledge_id in knowledge_id_list ]
226+ return list (knowledge_application_mapping_list ) + edit_knowledge_list
227+
176228 def edit (self , instance : Dict ):
177229 self .is_valid (raise_exception = True )
178230 tool = QuerySet (Tool ).filter (id = self .data .get ("tool_id" )).first ()
@@ -190,6 +242,26 @@ def edit(self, instance: Dict):
190242 'workspace_id' : workflow_id ,
191243 'work_flow' : instance .get ('work_flow' )
192244 })
245+ # 当前用户可修改关联的知识库列表
246+ tool_knowledge_id_list = [str (knowledge .get ('id' )) for knowledge in
247+ self .list_knowledge (with_valid = False )]
248+ knowledge_id_list = []
249+ if 'knowledge_id_list' in instance :
250+ # 当前用户可修改关联的知识库列表
251+ application_knowledge_id_list = [str (knowledge .get ('id' )) for knowledge in
252+ self .list_knowledge (with_valid = False )]
253+ knowledge_id_list = instance .get ('knowledge_id_list' )
254+ for knowledge_id in knowledge_id_list :
255+ if not application_knowledge_id_list .__contains__ (knowledge_id ):
256+ message = lazy_format (_ ('Unknown knowledge base id {dataset_id}, unable to associate' ),
257+ dataset_id = knowledge_id )
258+ raise AppApiException (500 , str (message ))
259+
260+ update_resource_mapping_by_tool (self .data .get ("tool_id" ),
261+ self .get_tool_knowledge_mapping (
262+ tool_knowledge_id_list ,
263+ knowledge_id_list ,
264+ self .data .get ("tool_id" )))
193265 return self .one ()
194266 if instance .get ("work_flow_template" ):
195267 template_instance = instance .get ('work_flow_template' )
@@ -302,3 +374,18 @@ def get_appstore_templates(self):
302374 except Exception as e :
303375 maxkb_logger .error (f"fetch appstore tools error: { e } " )
304376 return {'apps' : [], 'additionalProperties' : {'tags' : []}}
377+
378+
379+
380+ def update_resource_mapping_by_tool (tool_id : str , other_resource_mapping = None ):
381+ from application .flow .tools import get_instance_resource , save_workflow_mapping
382+ from system_manage .models .resource_mapping import ResourceType
383+ if other_resource_mapping is None :
384+ other_resource_mapping = []
385+ tool = QuerySet (ToolWorkflow ).filter (tool_id = tool_id ).first ()
386+ instance_mapping = get_instance_resource (tool , ResourceType .TOOL , str (tool_id ),
387+ {})
388+ save_workflow_mapping (tool .work_flow , ResourceType .TOOL , str (tool_id ),
389+ instance_mapping + other_resource_mapping )
390+
391+ return
0 commit comments