diff --git a/ai_knowledge_base_v2/apps/admin-web/src/App.vue b/ai_knowledge_base_v2/apps/admin-web/src/App.vue index a7c3b44..94018c8 100644 --- a/ai_knowledge_base_v2/apps/admin-web/src/App.vue +++ b/ai_knowledge_base_v2/apps/admin-web/src/App.vue @@ -15,6 +15,15 @@ import type { ModelItem, } from "./types/api"; +type UserKnowledgePermissionRow = { + knowledgeId: number; + name: string; + status: number; + assigned: boolean; + effectiveAt: string; + expiredAt: string; +}; + const admin = ref(null); const activeMenu = ref("dashboard"); const loading = ref(false); @@ -34,6 +43,11 @@ const chatDetail = ref(null); const chatDetailOpen = ref(false); const recordTab = ref("chats"); const editingModelId = ref(null); +const editingKnowledgeId = ref(null); +const userPermissionOpen = ref(false); +const userPermissionLoading = ref(false); +const permissionUser = ref(null); +const userKnowledgePermissionRows = ref([]); const agentDebugging = ref(false); const agentPreviewMessages = ref<{ role: "user" | "assistant" | "system"; content: string }[]>([ { role: "assistant", content: "选择模型和知识库后,可以在这里调试 Agent 的真实问答效果。" }, @@ -245,13 +259,103 @@ async function saveUser(row: AdminUser) { await loadCurrentMenu(); } -async function saveKnowledge() { - await api.createKnowledge({ ...knowledgeForm }); - ElMessage.success("知识库已新增"); - Object.assign(knowledgeForm, { name: "", feishuSpaceId: "", feishuNodeId: "", status: 1, remark: "" }); +async function deleteUser(row: AdminUser) { + if (!window.confirm(`确认删除用户 ${row.phone} 吗?删除后前台将无法继续使用该账号。`)) return; + await api.deleteUser(row.id); + ElMessage.success("用户已删除"); await loadCurrentMenu(); } +async function openUserPermissions(row: AdminUser) { + permissionUser.value = row; + userPermissionOpen.value = true; + userPermissionLoading.value = true; + try { + const [knowledgeRows, detail] = await Promise.all([api.knowledge(), api.userKnowledgePermissions(row.id)]); + knowledge.value = knowledgeRows; + const permissionMap = new Map(detail.permissions.map((item) => [item.knowledgeId, item])); + userKnowledgePermissionRows.value = knowledgeRows.map((item) => { + const permission = permissionMap.get(item.id); + return { + knowledgeId: item.id, + name: item.name, + status: item.status, + assigned: Boolean(permission), + effectiveAt: permission?.effectiveAt ?? "", + expiredAt: permission?.expiredAt ?? "", + }; + }); + } finally { + userPermissionLoading.value = false; + } +} + +async function saveUserPermissions() { + if (!permissionUser.value) return; + await api.saveUserKnowledgePermissions(permissionUser.value.id, { + permissions: userKnowledgePermissionRows.value + .filter((item) => item.assigned) + .map((item) => ({ + knowledgeId: item.knowledgeId, + effectiveAt: item.effectiveAt || null, + expiredAt: item.expiredAt || null, + })), + }); + ElMessage.success("知识库权限已保存"); + userPermissionOpen.value = false; +} + +async function saveKnowledge() { + if (!knowledgeForm.name || !knowledgeForm.feishuSpaceId || !knowledgeForm.feishuNodeId) { + ElMessage.error("请填写知识库名称、SpaceID 和 NodeID"); + return; + } + if (editingKnowledgeId.value) { + await api.updateKnowledge(editingKnowledgeId.value, { ...knowledgeForm }); + ElMessage.success("知识库已更新"); + } else { + await api.createKnowledge({ ...knowledgeForm }); + ElMessage.success("知识库已新增"); + } + resetKnowledgeForm(); + await loadCurrentMenu(); +} + +async function saveKnowledgeRow(row: KnowledgeItem) { + await api.updateKnowledge(row.id, { + name: row.name, + feishuSpaceId: row.feishuSpaceId, + feishuNodeId: row.feishuNodeId, + status: row.status, + remark: row.remark ?? "", + }); + ElMessage.success("知识库状态已更新"); +} + +function editKnowledge(row: KnowledgeItem) { + editingKnowledgeId.value = row.id; + Object.assign(knowledgeForm, { + name: row.name, + feishuSpaceId: row.feishuSpaceId, + feishuNodeId: row.feishuNodeId, + status: row.status, + remark: row.remark ?? "", + }); +} + +async function deleteKnowledge(row: KnowledgeItem) { + if (!window.confirm(`确认删除知识库 ${row.name} 吗?已分配给用户的授权也会失效。`)) return; + await api.deleteKnowledge(row.id); + ElMessage.success("知识库已删除"); + if (editingKnowledgeId.value === row.id) resetKnowledgeForm(); + await loadCurrentMenu(); +} + +function resetKnowledgeForm() { + editingKnowledgeId.value = null; + Object.assign(knowledgeForm, { name: "", feishuSpaceId: "", feishuNodeId: "", status: 1, remark: "" }); +} + async function savePrompt() { const result = await api.savePrompt(promptContent.value); promptContent.value = result.promptContent; @@ -473,14 +577,16 @@ async function debugAgent() { ElMessage.error("请输入调试问题"); return; } - agentPreviewMessages.value.push({ role: "user", content: agentForm.question.trim() }); + const question = agentForm.question.trim(); + agentPreviewMessages.value.push({ role: "user", content: question }); + agentForm.question = ""; agentDebugging.value = true; try { const result: AgentDebugResult = await api.debugAgent({ promptContent: promptContent.value, modelId: agentForm.modelId, knowledgeIds: agentForm.knowledgeIds, - question: agentForm.question.trim(), + question, temperature: agentForm.temperature, topP: agentForm.topP, topK: agentForm.topK, @@ -599,8 +705,10 @@ function buildChatQuery() { + + @@ -608,25 +716,55 @@ function buildChatQuery() { - - + + + @@ -676,17 +814,8 @@ function buildChatQuery() { - - -
保存 Agent 提示词 - 发送调试 清空预览
@@ -707,6 +836,17 @@ function buildChatQuery() {
{{ message.content }}
+
+ + 发送 +
@@ -907,6 +1047,62 @@ function buildChatQuery() { + + + +