From 9002abfe61fa821497c1782aff248d8b6d588d06 Mon Sep 17 00:00:00 2001 From: baiyanyun Date: Tue, 14 Jul 2026 16:39:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=9F=A5=E8=AF=86=E5=BA=93?= =?UTF-8?q?=E5=AE=B9=E9=87=8F=E6=9D=83=E9=99=90=E4=B8=8E=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent/core/adapter/dto/ComponentDto.java | 3 + .../ComponentApplicationServiceImpl.java | 2 + .../mapper/KnowledgeDocumentMapper.xml | 8 +- .../man/ui/web/KnowledgeConfigController.java | 10 + .../ui/web/KnowledgeDocumentController.java | 12 + .../man/ui/web/KnowledgeQaController.java | 8 + .../ui/web/KnowledgeRawSegmentController.java | 7 + .../KnowledgeDocumentCustomAddRequest.java | 4 + .../KnowledgeWritePermissionChecker.java | 70 +++ ...KnowledgeDocumentCustomAddRequestTest.java | 34 ++ .../KnowledgeWritePermissionCheckerTest.java | 116 +++++ .../components/pages/KnowledgePage.tsx | 422 ++++++++++++------ .../src/renderer/services/core/auth.ts | 4 + .../src/renderer/services/core/knowledge.ts | 9 + .../src/renderer/services/core/setup.ts | 2 +- .../components/KnowledgePage.module.css | 118 ++++- 16 files changed, 669 insertions(+), 160 deletions(-) create mode 100644 qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-ui/src/main/java/com/xspaceagi/knowledge/man/ui/web/permission/KnowledgeWritePermissionChecker.java create mode 100644 qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-ui/src/test/java/com/xspaceagi/knowledge/man/ui/web/dto/document/KnowledgeDocumentCustomAddRequestTest.java create mode 100644 qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-ui/src/test/java/com/xspaceagi/knowledge/man/ui/web/permission/KnowledgeWritePermissionCheckerTest.java diff --git a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/ComponentDto.java b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/ComponentDto.java index c67cebc3..240c7341 100644 --- a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/ComponentDto.java +++ b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/ComponentDto.java @@ -42,6 +42,9 @@ public class ComponentDto implements Serializable { @Schema(description = "创建时间") private Date created; + @Schema(description = "资源占用空间,单位字节,知识库有效") + private Long fileSize; + private Long creatorId; @Schema(description = "创建者信息") diff --git a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/ComponentApplicationServiceImpl.java b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/ComponentApplicationServiceImpl.java index e0bd82b6..3c8b08fb 100644 --- a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/ComponentApplicationServiceImpl.java +++ b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/ComponentApplicationServiceImpl.java @@ -105,6 +105,8 @@ public class ComponentApplicationServiceImpl implements ComponentApplicationServ componentDto.setType(ComponentTypeEnum.Knowledge); componentDto.setExt(knowledgeConfigModel.getDataType()); componentDto.setIcon(knowledgeConfigModel.getIcon()); + Long fileSize = iKnowledgeConfigApplicationService.queryTotalFileSize(knowledgeConfigModel.getId()); + componentDto.setFileSize(fileSize == null ? 0L : fileSize); componentDto.setCreatorId(knowledgeConfigModel.getCreatorId()); UserDto userDto = userDtoMap.get(knowledgeConfigModel.getCreatorId()); if (userDto != null) { diff --git a/qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-infra/src/main/resources/mapper/KnowledgeDocumentMapper.xml b/qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-infra/src/main/resources/mapper/KnowledgeDocumentMapper.xml index a13950f5..a1873604 100644 --- a/qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-infra/src/main/resources/mapper/KnowledgeDocumentMapper.xml +++ b/qiming-backend/app-platform-modules/app-platform-knowledge/app-platform-knowledge-core-infra/src/main/resources/mapper/KnowledgeDocumentMapper.xml @@ -103,7 +103,13 @@ - + {canManageSelectedKnowledge && ( + + )} @@ -1563,6 +1680,13 @@ export default function KnowledgePage() { const joining = selectedKnowledgeId !== null && joiningIds.has(selectedKnowledgeId); const knowledgeForAction = knowledgeInfo || selectedKnowledgeComponent; + const owned = isKnowledgeOwner(knowledgeForAction); + const creator = (knowledgeForAction as KnowledgeComponent | null)?.creator; + const creatorName = + creator?.nickName || + creator?.userName || + knowledgeForAction?.creatorName || + "未知创建人"; return ( <> @@ -1584,6 +1708,12 @@ export default function KnowledgePage() { {knowledgeForAction?.name || "知识库详情"}

{knowledgeForAction?.name || "知识库详情"}

+
+ + {owned ? "我的知识库" : "只读知识库"} + + {!owned && 创建人:{creatorName}} +

{knowledgeForAction?.description || "暂无描述"}

@@ -1598,15 +1728,17 @@ export default function KnowledgePage() { > {joined ? "已加入对话" : "加入对话"} - + {owned && ( + + )}
diff --git a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/auth.ts b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/auth.ts index 1a15eca2..24285472 100644 --- a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/auth.ts +++ b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/auth.ts @@ -30,6 +30,7 @@ import { t } from "./i18n"; // ========== 类型定义 === export interface AuthUserInfo { id?: number; + userId?: number; username: string; displayName?: string; avatar?: string; @@ -333,6 +334,7 @@ export async function loginAndRegister( await setUserInfo({ id: response.id, + userId: response.userId, username, displayName: response.name, currentDomain: domain, @@ -509,6 +511,7 @@ export async function reRegisterClient(): Promise await setUserInfo({ ...currentUserInfo, id: response.id, + userId: response.userId, username: username || "", displayName: response.name, currentDomain: domain || currentUserInfo?.currentDomain, @@ -675,6 +678,7 @@ export async function syncConfigToServer(options?: { await setUserInfo({ ...currentUserInfo, id: response.id, + userId: response.userId, username: username || "", displayName: response.name, currentDomain: preservedCurrentDomain, diff --git a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/knowledge.ts b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/knowledge.ts index d6037ab3..55b5e033 100644 --- a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/knowledge.ts +++ b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/knowledge.ts @@ -74,7 +74,15 @@ export interface KnowledgeComponent { spaceId?: number; created?: string; modified?: string; + creatorId?: number; creatorName?: string; + creator?: { + id?: number; + userName?: string; + nickName?: string; + avatar?: string; + }; + permissions?: string[]; [key: string]: unknown; } @@ -91,6 +99,7 @@ export interface KnowledgeInfo { pubStatus?: string; created?: string; modified?: string; + creatorId?: number; creatorName?: string; workflowId?: string | number; workflowName?: string; diff --git a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/setup.ts b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/setup.ts index b8d1103f..e0c4a975 100644 --- a/qimingclaw/crates/agent-electron-client/src/renderer/services/core/setup.ts +++ b/qimingclaw/crates/agent-electron-client/src/renderer/services/core/setup.ts @@ -37,7 +37,7 @@ export interface AuthUserInfo { username: string; displayName?: string; token?: string; - userId?: string; + userId?: number; email?: string; currentDomain?: string; agentId?: number; diff --git a/qimingclaw/crates/agent-electron-client/src/renderer/styles/components/KnowledgePage.module.css b/qimingclaw/crates/agent-electron-client/src/renderer/styles/components/KnowledgePage.module.css index 088d158c..ac20874d 100644 --- a/qimingclaw/crates/agent-electron-client/src/renderer/styles/components/KnowledgePage.module.css +++ b/qimingclaw/crates/agent-electron-client/src/renderer/styles/components/KnowledgePage.module.css @@ -82,19 +82,20 @@ flex-wrap: wrap; } -.search, -.innerSearch { +.search { width: min(420px, 100%); } +.innerSearch { + width: min(360px, 100%); +} + .toolbarCreateButton { flex: 0 0 auto; } .search :global(.ant-input-affix-wrapper), -.search:global(.ant-input-affix-wrapper), -.innerSearch :global(.ant-input-affix-wrapper), -.innerSearch:global(.ant-input-affix-wrapper) { +.search:global(.ant-input-affix-wrapper) { height: 42px; border-radius: 8px; border-color: #dcd9d1; @@ -102,6 +103,35 @@ box-shadow: none; } +.innerSearch :global(.ant-input-group) { + display: flex; +} + +.innerSearch :global(.ant-input-affix-wrapper) { + height: 38px; + border-color: #dcd9d1; + border-radius: 7px 0 0 7px; + background: #ffffff; + box-shadow: none; +} + +.innerSearch :global(.ant-input-search-button) { + width: 42px; + height: 38px; + padding: 0; + border-color: #dcd9d1; + border-radius: 0 7px 7px 0 !important; + color: #5e625c; + background: #ffffff; + box-shadow: none; +} + +.innerSearch :global(.ant-input-affix-wrapper-focused), +.innerSearch :global(.ant-input-affix-wrapper:focus-within), +.innerSearch :global(.ant-input-search-button:hover) { + border-color: #74aaa5; +} + .count { margin-left: auto; color: #888b85; @@ -132,15 +162,17 @@ .grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + grid-template-columns: repeat(3, minmax(0, 340px)); gap: 16px; + justify-content: start; } .card { - min-height: 202px; + min-width: 0; + min-height: 218px; display: flex; flex-direction: column; - padding: 18px; + padding: 16px; background: #ffffff; border: 1px solid #e8e4dc; border-radius: 8px; @@ -210,11 +242,28 @@ white-space: nowrap; } -.cardTitle span { - display: block; - margin-top: 4px; +.cardOwnerRow { + min-width: 0; + display: flex; + align-items: center; + gap: 6px; + margin-top: 5px; +} + +.cardOwnerRow span { + min-width: 0; + overflow: hidden; color: #8a8d89; font-size: 12px; + line-height: 18px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ownerTag { + flex: 0 0 auto; + margin-inline-end: 0; + line-height: 18px; } .cardDescription { @@ -235,7 +284,7 @@ justify-content: space-between; gap: 12px; margin-top: auto; - padding-top: 14px; + padding-top: 12px; color: #8a8d89; font-size: 12px; } @@ -251,10 +300,19 @@ display: flex; align-items: center; gap: 8px; - margin-top: 14px; + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid #efede7; flex-wrap: wrap; } +.cardOwnerActions { + display: flex; + align-items: center; + gap: 6px; + margin-left: auto; +} + .detailHeader { align-items: flex-start; } @@ -274,6 +332,20 @@ white-space: nowrap; } +.detailOwnerRow { + min-width: 0; + display: flex; + align-items: center; + gap: 8px; + margin-top: 7px; + color: #777b75; + font-size: 12px; +} + +.detailOwnerRow :global(.ant-tag) { + margin-inline-end: 0; +} + .detailActions { flex: 0 0 auto; display: flex; @@ -504,6 +576,10 @@ } @media (max-width: 1180px) { + .grid { + grid-template-columns: repeat(2, minmax(0, 340px)); + } + .statRow { grid-template-columns: repeat(2, minmax(0, 1fr)); } @@ -533,4 +609,20 @@ .statRow { grid-template-columns: minmax(0, 1fr); } + + .grid { + grid-template-columns: minmax(0, 340px); + } +} + +@media (max-width: 420px) { + .grid { + grid-template-columns: minmax(0, 1fr); + } + + .cardMeta { + align-items: flex-start; + flex-direction: column; + gap: 4px; + } }