完善知识库容量权限与界面
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
||||
} from "antd";
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
BookOutlined,
|
||||
CheckOutlined,
|
||||
CloudUploadOutlined,
|
||||
DatabaseOutlined,
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
} from "@ant-design/icons";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
import ImageWithFallback from "../common/ImageWithFallback";
|
||||
import { getCurrentAuth } from "../../services/core/auth";
|
||||
import {
|
||||
AiAgentContext,
|
||||
AiManualComponent,
|
||||
@@ -183,6 +183,7 @@ function getPublishedWorkflowId(workflow: PublishedWorkflow): number {
|
||||
}
|
||||
|
||||
export default function KnowledgePage() {
|
||||
const [currentUserId, setCurrentUserId] = useState<number | null>(null);
|
||||
const [spaces, setSpaces] = useState<SpaceInfo[]>([]);
|
||||
const [selectedSpaceId, setSelectedSpaceId] = useState<number | null>(null);
|
||||
const [knowledges, setKnowledges] = useState<KnowledgeComponent[]>([]);
|
||||
@@ -280,6 +281,26 @@ export default function KnowledgePage() {
|
||||
[knowledges, selectedKnowledgeId],
|
||||
);
|
||||
|
||||
const isKnowledgeOwner = useCallback(
|
||||
(knowledge?: KnowledgeComponent | KnowledgeInfo | null) => {
|
||||
if (!knowledge) return false;
|
||||
const creator = (knowledge as KnowledgeComponent).creator;
|
||||
const creatorId = Number(knowledge.creatorId || creator?.id || 0);
|
||||
return Boolean(currentUserId && creatorId && currentUserId === creatorId);
|
||||
},
|
||||
[currentUserId],
|
||||
);
|
||||
|
||||
const canManageSelectedKnowledge = isKnowledgeOwner(
|
||||
knowledgeInfo || selectedKnowledgeComponent,
|
||||
);
|
||||
|
||||
const ensureCanManageSelectedKnowledge = useCallback(() => {
|
||||
if (canManageSelectedKnowledge) return true;
|
||||
message.warning("该知识库由其他用户创建,仅支持查看和加入对话");
|
||||
return false;
|
||||
}, [canManageSelectedKnowledge]);
|
||||
|
||||
const loadAgentComponents = useCallback(async () => {
|
||||
try {
|
||||
const context = await resolveAiAgentContext();
|
||||
@@ -489,6 +510,9 @@ export default function KnowledgePage() {
|
||||
useEffect(() => {
|
||||
loadSpaces();
|
||||
loadAgentComponents();
|
||||
void getCurrentAuth().then((auth) => {
|
||||
setCurrentUserId(auth.userInfo?.userId || null);
|
||||
});
|
||||
}, [loadAgentComponents, loadSpaces]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -530,6 +554,10 @@ export default function KnowledgePage() {
|
||||
const openKnowledgeForm = async (
|
||||
knowledge?: KnowledgeComponent | KnowledgeInfo,
|
||||
) => {
|
||||
if (knowledge && !isKnowledgeOwner(knowledge)) {
|
||||
message.warning("该知识库由其他用户创建,不能编辑");
|
||||
return;
|
||||
}
|
||||
setKnowledgeModalOpen(true);
|
||||
void (async () => {
|
||||
const spaceId =
|
||||
@@ -591,6 +619,10 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const saveKnowledge = async () => {
|
||||
if (editingKnowledge && !isKnowledgeOwner(editingKnowledge)) {
|
||||
message.warning("该知识库由其他用户创建,不能编辑");
|
||||
return;
|
||||
}
|
||||
let values: KnowledgeFormValues;
|
||||
try {
|
||||
values = await knowledgeForm.validateFields();
|
||||
@@ -643,6 +675,10 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const confirmDeleteKnowledge = (knowledge: KnowledgeComponent) => {
|
||||
if (!isKnowledgeOwner(knowledge)) {
|
||||
message.warning("该知识库由其他用户创建,不能删除");
|
||||
return;
|
||||
}
|
||||
const knowledgeId = getKnowledgeId(knowledge);
|
||||
Modal.confirm({
|
||||
title: "删除知识库",
|
||||
@@ -767,6 +803,7 @@ export default function KnowledgePage() {
|
||||
const files = Array.from(event.target.files || []);
|
||||
event.target.value = "";
|
||||
if (!files.length || !selectedKnowledgeId) return;
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
|
||||
const validationError = files.map(validateKnowledgeFile).find(Boolean);
|
||||
if (validationError) {
|
||||
@@ -792,6 +829,7 @@ export default function KnowledgePage() {
|
||||
|
||||
const saveCustomDocument = async () => {
|
||||
if (!selectedKnowledgeId) return;
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
const values = await customDocForm.validateFields();
|
||||
setSavingCustomDoc(true);
|
||||
try {
|
||||
@@ -812,6 +850,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const openRenameDocument = (doc: KnowledgeDocumentInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
setRenamingDoc(doc);
|
||||
renameDocForm.setFieldsValue({ name: doc.name });
|
||||
setRenameDocModalOpen(true);
|
||||
@@ -819,6 +858,7 @@ export default function KnowledgePage() {
|
||||
|
||||
const saveDocumentName = async () => {
|
||||
if (!renamingDoc) return;
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
const values = await renameDocForm.validateFields();
|
||||
setSavingRename(true);
|
||||
try {
|
||||
@@ -856,6 +896,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const confirmDeleteDocument = (doc: KnowledgeDocumentInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
Modal.confirm({
|
||||
title: "删除文档",
|
||||
content: `确认删除「${doc.name}」吗?`,
|
||||
@@ -874,6 +915,7 @@ export default function KnowledgePage() {
|
||||
doc: KnowledgeDocumentInfo,
|
||||
action: "qa" | "embedding" | "retry",
|
||||
) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
try {
|
||||
if (action === "qa") {
|
||||
await generateKnowledgeDocumentQa(doc.id);
|
||||
@@ -892,6 +934,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const openSegmentModal = (segment?: KnowledgeRawSegmentInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
setEditingSegment(segment || null);
|
||||
segmentForm.setFieldsValue({
|
||||
rawTxt: segment?.rawTxt || "",
|
||||
@@ -901,6 +944,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const saveSegment = async () => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
const spaceId =
|
||||
selectedDocument?.spaceId || knowledgeInfo?.spaceId || selectedSpaceId;
|
||||
if (!selectedDocument || !spaceId) return;
|
||||
@@ -932,6 +976,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const confirmDeleteSegment = (segment: KnowledgeRawSegmentInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
Modal.confirm({
|
||||
title: "删除分段",
|
||||
content: "确认删除该分段吗?",
|
||||
@@ -947,6 +992,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const openQaModal = (qa?: KnowledgeQaInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
setEditingQa(qa || null);
|
||||
qaForm.setFieldsValue({
|
||||
question: qa?.question || "",
|
||||
@@ -957,6 +1003,7 @@ export default function KnowledgePage() {
|
||||
|
||||
const saveQa = async () => {
|
||||
if (!selectedKnowledgeId) return;
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
const values = await qaForm.validateFields();
|
||||
try {
|
||||
if (editingQa) {
|
||||
@@ -983,6 +1030,7 @@ export default function KnowledgePage() {
|
||||
};
|
||||
|
||||
const confirmDeleteQa = (qa: KnowledgeQaInfo) => {
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
Modal.confirm({
|
||||
title: "删除 QA",
|
||||
content: "确认删除该问答吗?",
|
||||
@@ -1001,6 +1049,7 @@ export default function KnowledgePage() {
|
||||
const file = event.target.files?.[0];
|
||||
event.target.value = "";
|
||||
if (!file || !selectedKnowledgeId) return;
|
||||
if (!ensureCanManageSelectedKnowledge()) return;
|
||||
try {
|
||||
await importKnowledgeQaExcel({ kbId: selectedKnowledgeId, file });
|
||||
message.success("QA 已导入");
|
||||
@@ -1068,7 +1117,7 @@ export default function KnowledgePage() {
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 260,
|
||||
width: canManageSelectedKnowledge ? 260 : 120,
|
||||
fixed: "right",
|
||||
render: (_, record) => (
|
||||
<div className={styles.tableActions}>
|
||||
@@ -1082,34 +1131,38 @@ export default function KnowledgePage() {
|
||||
>
|
||||
分段
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "qa")}
|
||||
>
|
||||
生成 QA
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "embedding")}
|
||||
>
|
||||
向量化
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "retry")}
|
||||
>
|
||||
重试
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openRenameDocument(record)}
|
||||
>
|
||||
重命名
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "qa")}
|
||||
>
|
||||
生成 QA
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "embedding")}
|
||||
>
|
||||
向量化
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => runDocumentAction(record, "retry")}
|
||||
>
|
||||
重试
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openRenameDocument(record)}
|
||||
>
|
||||
重命名
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{record.docUrl && (
|
||||
<Button
|
||||
type="link"
|
||||
@@ -1119,14 +1172,16 @@ export default function KnowledgePage() {
|
||||
打开
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteDocument(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteDocument(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -1149,29 +1204,33 @@ export default function KnowledgePage() {
|
||||
width: 170,
|
||||
render: (_, record) => formatDateTime(record.modified || record.created),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<div className={styles.tableActions}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openSegmentModal(record)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteSegment(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...(canManageSelectedKnowledge
|
||||
? [
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
render: (_: unknown, record: KnowledgeRawSegmentInfo) => (
|
||||
<div className={styles.tableActions}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openSegmentModal(record)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteSegment(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
const qaColumns: ColumnsType<KnowledgeQaInfo> = [
|
||||
@@ -1191,25 +1250,33 @@ export default function KnowledgePage() {
|
||||
width: 170,
|
||||
render: (_, record) => formatDateTime(record.modified || record.created),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<div className={styles.tableActions}>
|
||||
<Button type="link" size="small" onClick={() => openQaModal(record)}>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteQa(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...(canManageSelectedKnowledge
|
||||
? [
|
||||
{
|
||||
title: "操作",
|
||||
width: 120,
|
||||
render: (_: unknown, record: KnowledgeQaInfo) => (
|
||||
<div className={styles.tableActions}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openQaModal(record)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => confirmDeleteQa(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
const renderKnowledgeIcon = (
|
||||
@@ -1295,6 +1362,12 @@ export default function KnowledgePage() {
|
||||
<div className={styles.grid}>
|
||||
{filteredKnowledges.map((knowledge) => {
|
||||
const knowledgeId = getKnowledgeId(knowledge);
|
||||
const owned = isKnowledgeOwner(knowledge);
|
||||
const creatorName =
|
||||
knowledge.creator?.nickName ||
|
||||
knowledge.creator?.userName ||
|
||||
knowledge.creatorName ||
|
||||
"未知创建人";
|
||||
const joinedComponent = joinedKnowledgeMap.get(knowledgeId);
|
||||
const joined =
|
||||
!!joinedComponent &&
|
||||
@@ -1311,7 +1384,19 @@ export default function KnowledgePage() {
|
||||
</div>
|
||||
<div className={styles.cardTitle}>
|
||||
<h3>{knowledge.name}</h3>
|
||||
<span>知识库资源</span>
|
||||
<div className={styles.cardOwnerRow}>
|
||||
<Tag
|
||||
color={owned ? "cyan" : "default"}
|
||||
className={styles.ownerTag}
|
||||
>
|
||||
{owned ? "我的知识库" : "只读"}
|
||||
</Tag>
|
||||
{!owned && (
|
||||
<span title={creatorName}>
|
||||
创建人:{creatorName}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className={styles.cardDescription}>
|
||||
@@ -1319,9 +1404,14 @@ export default function KnowledgePage() {
|
||||
</p>
|
||||
<div className={styles.cardMeta}>
|
||||
<span>
|
||||
{formatBytes(Number(knowledge.fileSize || 0))}
|
||||
容量 {formatBytes(Number(knowledge.fileSize || 0))}
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
title={formatDateTime(
|
||||
knowledge.modified || knowledge.created,
|
||||
)}
|
||||
>
|
||||
更新{" "}
|
||||
{formatDateTime(
|
||||
knowledge.modified || knowledge.created,
|
||||
)}
|
||||
@@ -1329,6 +1419,7 @@ export default function KnowledgePage() {
|
||||
</div>
|
||||
<div className={styles.cardActions}>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon={joined ? <CheckOutlined /> : <TeamOutlined />}
|
||||
loading={joiningIds.has(knowledgeId)}
|
||||
@@ -1339,25 +1430,33 @@ export default function KnowledgePage() {
|
||||
>
|
||||
{joined ? "已加入" : "加入对话"}
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
openKnowledgeForm(knowledge);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
confirmDeleteKnowledge(knowledge);
|
||||
}}
|
||||
/>
|
||||
{owned && (
|
||||
<div className={styles.cardOwnerActions}>
|
||||
<Tooltip title="编辑知识库">
|
||||
<Button
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
aria-label="编辑知识库"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
openKnowledgeForm(knowledge);
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="删除知识库">
|
||||
<Button
|
||||
size="small"
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
aria-label="删除知识库"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
confirmDeleteKnowledge(knowledge);
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
@@ -1376,7 +1475,11 @@ export default function KnowledgePage() {
|
||||
allowClear
|
||||
placeholder="搜索文档"
|
||||
value={documentKeyword}
|
||||
onChange={(event) => setDocumentKeyword(event.target.value)}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value;
|
||||
setDocumentKeyword(value);
|
||||
if (!value) void loadDocuments("");
|
||||
}}
|
||||
onSearch={(value) => loadDocuments(value)}
|
||||
className={styles.innerSearch}
|
||||
/>
|
||||
@@ -1387,22 +1490,26 @@ export default function KnowledgePage() {
|
||||
className={styles.hiddenInput}
|
||||
onChange={handleDocumentFiles}
|
||||
/>
|
||||
<Button
|
||||
icon={<CloudUploadOutlined />}
|
||||
loading={uploadingDocs}
|
||||
onClick={() => documentFileInputRef.current?.click()}
|
||||
>
|
||||
上传文档
|
||||
</Button>
|
||||
<Button
|
||||
icon={<FileAddOutlined />}
|
||||
onClick={() => {
|
||||
customDocForm.resetFields();
|
||||
setCustomDocModalOpen(true);
|
||||
}}
|
||||
>
|
||||
自定义文本
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<>
|
||||
<Button
|
||||
icon={<CloudUploadOutlined />}
|
||||
loading={uploadingDocs}
|
||||
onClick={() => documentFileInputRef.current?.click()}
|
||||
>
|
||||
上传文档
|
||||
</Button>
|
||||
<Button
|
||||
icon={<FileAddOutlined />}
|
||||
onClick={() => {
|
||||
customDocForm.resetFields();
|
||||
setCustomDocModalOpen(true);
|
||||
}}
|
||||
>
|
||||
自定义文本
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Tooltip title="刷新文档状态">
|
||||
<Button icon={<ReloadOutlined />} onClick={refreshDocumentStatus} />
|
||||
</Tooltip>
|
||||
@@ -1443,13 +1550,15 @@ export default function KnowledgePage() {
|
||||
}}
|
||||
options={documents.map((doc) => ({ label: doc.name, value: doc.id }))}
|
||||
/>
|
||||
<Button
|
||||
icon={<PlusOutlined />}
|
||||
disabled={!selectedDocument}
|
||||
onClick={() => openSegmentModal()}
|
||||
>
|
||||
新增分段
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<Button
|
||||
icon={<PlusOutlined />}
|
||||
disabled={!selectedDocument}
|
||||
onClick={() => openSegmentModal()}
|
||||
>
|
||||
新增分段
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
icon={<ReloadOutlined />}
|
||||
disabled={!selectedDocument}
|
||||
@@ -1498,13 +1607,19 @@ export default function KnowledgePage() {
|
||||
allowClear
|
||||
placeholder="搜索问题"
|
||||
value={qaKeyword}
|
||||
onChange={(event) => setQaKeyword(event.target.value)}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value;
|
||||
setQaKeyword(value);
|
||||
if (!value) void loadQaList("");
|
||||
}}
|
||||
onSearch={(value) => loadQaList(value)}
|
||||
className={styles.innerSearch}
|
||||
/>
|
||||
<Button icon={<PlusOutlined />} onClick={() => openQaModal()}>
|
||||
新增 QA
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<Button icon={<PlusOutlined />} onClick={() => openQaModal()}>
|
||||
新增 QA
|
||||
</Button>
|
||||
)}
|
||||
<input
|
||||
ref={qaFileInputRef}
|
||||
type="file"
|
||||
@@ -1512,12 +1627,14 @@ export default function KnowledgePage() {
|
||||
className={styles.hiddenInput}
|
||||
onChange={handleQaImport}
|
||||
/>
|
||||
<Button
|
||||
icon={<CloudUploadOutlined />}
|
||||
onClick={() => qaFileInputRef.current?.click()}
|
||||
>
|
||||
导入 Excel
|
||||
</Button>
|
||||
{canManageSelectedKnowledge && (
|
||||
<Button
|
||||
icon={<CloudUploadOutlined />}
|
||||
onClick={() => qaFileInputRef.current?.click()}
|
||||
>
|
||||
导入 Excel
|
||||
</Button>
|
||||
)}
|
||||
<Button icon={<DownloadOutlined />} onClick={handleDownloadQaTemplate}>
|
||||
下载模板
|
||||
</Button>
|
||||
@@ -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() {
|
||||
<strong>{knowledgeForAction?.name || "知识库详情"}</strong>
|
||||
</div>
|
||||
<h1>{knowledgeForAction?.name || "知识库详情"}</h1>
|
||||
<div className={styles.detailOwnerRow}>
|
||||
<Tag color={owned ? "cyan" : "default"}>
|
||||
{owned ? "我的知识库" : "只读知识库"}
|
||||
</Tag>
|
||||
{!owned && <span>创建人:{creatorName}</span>}
|
||||
</div>
|
||||
<p>{knowledgeForAction?.description || "暂无描述"}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1598,15 +1728,17 @@ export default function KnowledgePage() {
|
||||
>
|
||||
{joined ? "已加入对话" : "加入对话"}
|
||||
</Button>
|
||||
<Button
|
||||
icon={<EditOutlined />}
|
||||
disabled={!knowledgeForAction}
|
||||
onClick={() =>
|
||||
knowledgeForAction && openKnowledgeForm(knowledgeForAction)
|
||||
}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
{owned && (
|
||||
<Button
|
||||
icon={<EditOutlined />}
|
||||
disabled={!knowledgeForAction}
|
||||
onClick={() =>
|
||||
knowledgeForAction && openKnowledgeForm(knowledgeForAction)
|
||||
}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
<main className={styles.detailContent}>
|
||||
|
||||
Reference in New Issue
Block a user