feat: 递归导入只需输入NodeToken,自动获取SpaceID
- feishu_service.py: import_nodes_from_parent 去掉 space_id 参数, 通过 get_node_info 自动获取 space_id - admin_knowledge.py: import API 去掉 spaceId 参数 - App.vue: 前端去掉 SpaceID 输入框,只需输入 NodeToken
This commit is contained in:
@@ -37,7 +37,6 @@ const chatDetailOpen = ref(false);
|
|||||||
const recordTab = ref("chats");
|
const recordTab = ref("chats");
|
||||||
const editingModelId = ref<number | null>(null);
|
const editingModelId = ref<number | null>(null);
|
||||||
const editingKnowledgeId = ref<number | null>(null);
|
const editingKnowledgeId = ref<number | null>(null);
|
||||||
const batchSpaceId = ref("");
|
|
||||||
const batchParentToken = ref("");
|
const batchParentToken = ref("");
|
||||||
const batchImporting = ref(false);
|
const batchImporting = ref(false);
|
||||||
const agentDebugging = ref(false);
|
const agentDebugging = ref(false);
|
||||||
@@ -593,17 +592,15 @@ function resetKnowledgeForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function batchImportKnowledge() {
|
async function batchImportKnowledge() {
|
||||||
const spaceId = batchSpaceId.value.trim();
|
|
||||||
const parentToken = batchParentToken.value.trim();
|
const parentToken = batchParentToken.value.trim();
|
||||||
if (!spaceId || !parentToken) {
|
if (!parentToken) {
|
||||||
ElMessage.warning("请输入 SpaceID 和父节点 NodeToken");
|
ElMessage.warning("请输入父节点 NodeToken");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
batchImporting.value = true;
|
batchImporting.value = true;
|
||||||
try {
|
try {
|
||||||
const result = await api.importKnowledgeFromSpace(JSON.stringify({ spaceId, parent_node_token: parentToken }));
|
const result = await api.importKnowledgeFromSpace({ parent_node_token: parentToken });
|
||||||
ElMessage.success(`导入完成:新增 ${result.imported} 个,跳过 ${result.skipped} 个`);
|
ElMessage.success(`导入完成:新增 ${result.imported} 个,跳过 ${result.skipped} 个`);
|
||||||
batchSpaceId.value = "";
|
|
||||||
batchParentToken.value = "";
|
batchParentToken.value = "";
|
||||||
await loadCurrentMenu();
|
await loadCurrentMenu();
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -1128,9 +1125,8 @@ function buildChatQuery() {
|
|||||||
|
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<div class="batch-import-row">
|
<div class="batch-import-row">
|
||||||
<el-input v-model="batchSpaceId" placeholder="SpaceID" style="width: 220px" />
|
<el-input v-model="batchParentToken" placeholder="输入父节点 NodeToken(如 wikcnXXX),递归导入所有子节点" style="max-width: 400px" />
|
||||||
<el-input v-model="batchParentToken" placeholder="父节点 NodeToken(如 wikcnXXX)" style="width: 260px" />
|
<el-button type="primary" @click="batchImportKnowledge" :loading="batchImporting">递归导入</el-button>
|
||||||
<el-button type="primary" @click="batchImportKnowledge" :loading="batchImporting">递归导入子节点</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="knowledge" stripe>
|
<el-table :data="knowledge" stripe>
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
|
|||||||
@@ -28,12 +28,11 @@ def import_knowledge_from_space(
|
|||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
current_admin: Admin = Depends(get_current_admin),
|
current_admin: Admin = Depends(get_current_admin),
|
||||||
) -> dict:
|
) -> dict:
|
||||||
space_id = payload.get("spaceId", "").strip()
|
|
||||||
parent_node_token = payload.get("parent_node_token", "").strip()
|
parent_node_token = payload.get("parent_node_token", "").strip()
|
||||||
if not space_id or not parent_node_token:
|
if not parent_node_token:
|
||||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="SpaceID 和父节点 Token 不能为空")
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="父节点 NodeToken 不能为空")
|
||||||
|
|
||||||
nodes = FeishuKnowledgeService.import_nodes_from_parent(space_id, parent_node_token, db)
|
nodes = FeishuKnowledgeService.import_nodes_from_parent(parent_node_token, db)
|
||||||
if not nodes:
|
if not nodes:
|
||||||
return api_success({"imported": 0, "skipped": 0, "nodes": []})
|
return api_success({"imported": 0, "skipped": 0, "nodes": []})
|
||||||
|
|
||||||
|
|||||||
@@ -333,12 +333,12 @@ class FeishuKnowledgeService:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def import_nodes_from_parent(
|
def import_nodes_from_parent(
|
||||||
cls,
|
cls,
|
||||||
space_id: str,
|
|
||||||
parent_node_token: str,
|
parent_node_token: str,
|
||||||
db: Session | None = None,
|
db: Session | None = None,
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
"""从指定节点递归获取所有子节点,用于批量导入知识库。
|
"""从指定节点递归获取所有子节点,用于批量导入知识库。
|
||||||
不需要空间级别权限,只需要对 parent_node_token 所在节点有查看权限。
|
不需要空间级别权限,只需要对 parent_node_token 所在节点有查看权限。
|
||||||
|
自动通过 node_info 获取 space_id,调用方无需手动传入。
|
||||||
"""
|
"""
|
||||||
config = _feishu_retrieval_config(db)
|
config = _feishu_retrieval_config(db)
|
||||||
if not config.app_id or not config.app_secret:
|
if not config.app_id or not config.app_secret:
|
||||||
@@ -347,6 +347,15 @@ class FeishuKnowledgeService:
|
|||||||
provider="feishu",
|
provider="feishu",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 先通过 node_token 获取 space_id
|
||||||
|
node_info = _get_wiki_node_info(parent_node_token, config)
|
||||||
|
space_id = node_info.get("space_id", "")
|
||||||
|
if not space_id:
|
||||||
|
raise ExternalServiceError(
|
||||||
|
f"无法获取节点 {parent_node_token} 所属的 SpaceID",
|
||||||
|
provider="feishu",
|
||||||
|
)
|
||||||
|
|
||||||
all_nodes: list[dict] = []
|
all_nodes: list[dict] = []
|
||||||
visited: set[str] = set()
|
visited: set[str] = set()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user