[fix]修复服务启动 (#3)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,7 +26,6 @@ time.log
|
||||
celerybeat-schedule.db
|
||||
search_results.json
|
||||
*.txt
|
||||
*.json
|
||||
migrations/versions
|
||||
tmp
|
||||
files
|
||||
|
||||
@@ -60,6 +60,13 @@ LOG_LEVEL=INFO
|
||||
# 如需自动迁移数据库:设置 DB_AUTO_UPGRADE=true 或手动执行
|
||||
alembic upgrade head
|
||||
|
||||
# 激活虚拟环境
|
||||
api\.venv\Scripts\activate
|
||||
|
||||
# 目录切换到api下
|
||||
cd api
|
||||
|
||||
|
||||
# 启动开发服务
|
||||
uvicorn app.main:app --reload --port 8000
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ This module provides utilities for detecting and processing multimodal inputs
|
||||
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from app.core.memory.agent.multimodal.speech_model import Vico_recognition
|
||||
# TODO 后续更新
|
||||
# from app.core.memory.agent.multimodal.speech_model import Vico_recognition
|
||||
from app.core.memory.agent.utils.llm_tools import picture_model_requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
"""
|
||||
MemSci 记忆系统主入口 - 重构版本
|
||||
|
||||
该模块是重构后的记忆系统主入口,使用新的模块化架构。
|
||||
旧版本入口(app/core/memory/src/main.py)已删除。
|
||||
MemSci 记忆系统主入口
|
||||
|
||||
主要功能:
|
||||
1. 协调整个知识提取流水线
|
||||
|
||||
@@ -29,7 +29,8 @@ from app.core.memory.agent.utils.mcp_tools import get_mcp_server_config
|
||||
from app.core.memory.agent.utils.type_classifier import status_typle
|
||||
from app.db import get_db
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.core.memory.analytics.hot_memory_tags import get_hot_memory_tags
|
||||
# TODO 后续更新
|
||||
# from app.core.memory.analytics.hot_memory_tags import get_hot_memory_tags
|
||||
from app.core.memory.utils.llm.llm_utils import get_llm_client
|
||||
from app.schemas.memory_storage_schema import ApiResponse, ok, fail
|
||||
from app.models.knowledge_model import Knowledge, KnowledgeType
|
||||
|
||||
@@ -23,10 +23,11 @@ from app.schemas.memory_storage_schema import (
|
||||
)
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.core.memory.analytics.hot_memory_tags import get_hot_memory_tags
|
||||
from app.core.memory.analytics.memory_insight import MemoryInsight
|
||||
from app.core.memory.analytics.recent_activity_stats import get_recent_activity_stats
|
||||
from app.core.memory.analytics.user_summary import generate_user_summary
|
||||
# TODO 后续更新
|
||||
# from app.core.memory.analytics.hot_memory_tags import get_hot_memory_tags
|
||||
# from app.core.memory.analytics.memory_insight import MemoryInsight
|
||||
# from app.core.memory.analytics.recent_activity_stats import get_recent_activity_stats
|
||||
# from app.core.memory.analytics.user_summary import generate_user_summary
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
32
web/.gitignore
vendored
Normal file
32
web/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
package-lock.json
|
||||
|
||||
# 文档和截图(不上传到仓库)
|
||||
操作说明.md
|
||||
记忆熊系统功能使用说明.md
|
||||
截图清单.md
|
||||
images/
|
||||
@@ -1,205 +0,0 @@
|
||||
# i18n 中英文对比报告
|
||||
|
||||
## 📊 统计概览
|
||||
|
||||
- **中文键总数**: 1136
|
||||
- **英文键总数**: 1052
|
||||
- **中文缺失**: 27 个键
|
||||
- **英文缺失**: 111 个键
|
||||
|
||||
---
|
||||
|
||||
## ❌ 英文缺失的翻译(111个)
|
||||
|
||||
### 1. Application 模块 (3个)
|
||||
- `application.cluster` - 集群
|
||||
- `application.clusterDesc` - 创建Agent集群
|
||||
- `application.fullAmount` - 全量
|
||||
|
||||
### 2. Role 角色管理模块 (15个)
|
||||
- `role.roleManagement` - 角色管理
|
||||
- `role.roleId` - 角色ID
|
||||
- `role.roleName` - 角色名称
|
||||
- `role.roleCode` - 角色编码
|
||||
- `role.description` - 角色描述
|
||||
- `role.status` - 状态
|
||||
- `role.enabled` - 已启用
|
||||
- `role.disabled` - 已停用
|
||||
- `role.createTime` - 创建时间
|
||||
- `role.createRole` - 新建角色
|
||||
- `role.editRole` - 编辑角色
|
||||
- `role.roleTemplate` - 角色模板
|
||||
- `role.emptyTemplate` - 空模板
|
||||
- `role.adminTemplate` - 管理员模板
|
||||
- `role.userTemplate` - 用户模板
|
||||
- `role.confirmDelete` - 确定要删除这个角色吗?
|
||||
- `role.createSuccess` - 角色创建成功
|
||||
- `role.updateSuccess` - 角色更新成功
|
||||
- `role.deleteSuccess` - 角色删除成功
|
||||
- `role.createFailed` - 角色创建失败
|
||||
- `role.updateFailed` - 角色更新失败
|
||||
- `role.deleteFailed` - 角色删除失败
|
||||
|
||||
### 3. Tenant 租户管理模块 (20个)
|
||||
- `tenant.tenantId` - 租户ID
|
||||
- `tenant.tenantName` - 租户名称
|
||||
- `tenant.contactPerson` - 联系人
|
||||
- `tenant.contactInfo` - 联系方式
|
||||
- `tenant.status` - 状态
|
||||
- `tenant.enabled` - 启用
|
||||
- `tenant.disabled` - 禁用
|
||||
- `tenant.expiryDate` - 到期时间
|
||||
- `tenant.createTenant` - 新增租户
|
||||
- `tenant.editTenant` - 编辑租户
|
||||
- `tenant.searchPlaceholder` - 搜索租户ID、名称、联系人或联系方式
|
||||
- `tenant.confirmDelete` - 确定要删除该租户吗?
|
||||
- `tenant.confirmBatchDelete` - 确定要批量删除选中的租户吗?
|
||||
- `tenant.fetchFailed` - 获取租户数据失败
|
||||
- `tenant.batchEnableSuccess` - 批量启用成功
|
||||
- `tenant.batchEnableFailed` - 批量启用失败
|
||||
- `tenant.batchDisableSuccess` - 批量停用成功
|
||||
- `tenant.batchDisableFailed` - 批量停用失败
|
||||
- `tenant.exportSuccess` - 导出成功
|
||||
- `tenant.batchDeleteSuccess` - 批量删除成功
|
||||
- `tenant.batchDeleteFailed` - 批量删除失败
|
||||
- `tenant.saveFailed` - 保存失败
|
||||
- `tenant.batchImport` - 批量导入
|
||||
|
||||
### 4. User 用户管理模块 (13个)
|
||||
- `user.tenantName` - 所属租户
|
||||
- `user.password` - 密码
|
||||
- `user.expiryDate` - 有效期
|
||||
- `user.expiryDateDue` - 有效期至
|
||||
- `user.batchImport` - 批量导入
|
||||
- `user.batchImportUser` - 批量导入用户
|
||||
- `user.downloadTemplate` - 下载导入模板
|
||||
- `user.templateDownloadSuccess` - 模板下载成功
|
||||
- `user.startImport` - 开始导入
|
||||
- `user.batchImportSuccess` - 批量导入成功
|
||||
- `user.importFailed` - 导入失败,请检查文件格式
|
||||
- `user.noFileSelected` - 请选择要导入的文件
|
||||
- `user.onlyXlsxOrCsv` - 只能上传 .xlsx 或 .csv 格式的文件
|
||||
- `user.reselect` - 重新选择
|
||||
- `user.noFileSelectedTip` - 未选择任何文件
|
||||
- `user.downloadTemplateTip` - 请下载模板,填写用户信息后上传。
|
||||
|
||||
### 5. Product 产品管理模块 (13个)
|
||||
- `product.applicationManagement` - 应用管理
|
||||
- `product.createApplication` - 创建应用
|
||||
- `product.applicationName` - 应用名称
|
||||
- `product.applicationIcon` - 应用图标
|
||||
- `product.applicationNameRequired` - 请输入应用名称
|
||||
- `product.associationStatus` - 关联状态
|
||||
- `product.associated` - 已关联
|
||||
- `product.notAssociated` - 未关联
|
||||
- `product.unassociate` - 解除关联
|
||||
- `product.unassociateSuccess` - 解除关联成功
|
||||
- `product.unassociateFailed` - 解除关联失败
|
||||
- `product.viewKey` - 查看KEY
|
||||
- `product.viewStats` - 查看统计
|
||||
- `product.disableSuccess` - 停用成功
|
||||
- `product.enableSuccess` - 启用成功
|
||||
- `product.operationFailed` - 操作失败
|
||||
|
||||
### 6. 其他模块 (47个)
|
||||
- `count` - 计数: {{count}}
|
||||
- `increment` - 增加
|
||||
- `decrement` - 减少
|
||||
- `reset` - 重置
|
||||
- `switchLanguage` - 切换语言
|
||||
- `home.title` - 首页
|
||||
- `home.welcome` - 欢迎使用我们的带单页路由的 React 应用!
|
||||
- `home.counterCard` - 计数器演示
|
||||
- `home.aboutCard` - 关于我们
|
||||
- `home.workflowCard` - 工作流编辑器
|
||||
- `home.websocketDemoCard` - WebSocket 演示
|
||||
- `home.sseDemoCard` - SSE演示
|
||||
- `workflow.title` - 工作流编辑器
|
||||
- `workflow.description` - 拖拽节点创建连接,构建您的工作流程。点击节点可进行配置。
|
||||
- `workflow.addNode` - 添加节点
|
||||
- `workflow.deleteNode` - 删除选中
|
||||
- `workflow.saveWorkflow` - 保存工作流
|
||||
- `workflow.startNode` - 触发节点
|
||||
- `workflow.conditionNode` - 条件判断
|
||||
- `workflow.actionNode` - 执行动作
|
||||
- `workflow.endNode` - 结束节点
|
||||
- `workflow.newNode` - 新节点
|
||||
- `workflow.node` - 节点
|
||||
- `workflow.nodesCreated` - 已创建节点
|
||||
- `workflow.loadingNodes` - 正在加载节点 {{progress}}%
|
||||
- `workflow.loadingFailed` - 加载节点失败
|
||||
- `workflow.create5kNodes` - 创建5000节点
|
||||
- `workflow.create10kNodes` - 创建10000节点
|
||||
- `notFound.title` - 页面未找到
|
||||
- `notFound.description` - 请求的页面不存在。
|
||||
- `notFound.backToHome` - 返回首页
|
||||
|
||||
---
|
||||
|
||||
## ✅ 中文缺失的翻译(27个)
|
||||
|
||||
### 1. Common 通用模块 (1个)
|
||||
- `common.operateSuccess` - Operation successful
|
||||
|
||||
### 2. KnowledgeBase 知识库模块 (3个)
|
||||
- `knowledgeBase.models` - Model
|
||||
- `knowledgeBase.owner` - Owner
|
||||
- `knowledgeBase.operation` - Operation
|
||||
|
||||
### 3. Application 应用模块 (15个)
|
||||
- `application.multi_agent` - Cluster
|
||||
- `application.multi_agentDesc` - Create an Agent Cluster
|
||||
- `application.current` - Current
|
||||
- `application.versionName` - Version Name
|
||||
- `application.versionNameTip` - Version number format: v[major version number].[next version number].[revision number] (e.g. v1.3.0)
|
||||
- `application.agentName` - Agent Name
|
||||
- `application.roleType` - Role Type
|
||||
- `application.coordinator` - Coordinator
|
||||
- `application.analyzer` - Analyzer
|
||||
- `application.executor` - Executor
|
||||
- `application.reviewer` - Reviewer
|
||||
- `application.updateSubAgent` - Update Sub Agent
|
||||
- `application.subAgentMaxLength` - Sub Agent maximum {{maxLength}}
|
||||
- `application.capabilities` - Capabilities
|
||||
|
||||
### 4. Space 空间模块 (5个)
|
||||
- `space.storageType` - Storage Type
|
||||
- `space.rag` - RAG storage
|
||||
- `space.ragDesc` - Based on vector retrieval, suitable for document Q&A and semantic search
|
||||
- `space.neo4j` - Graph storage
|
||||
- `space.neo4jDesc` - Based on knowledge graph, suitable for relational reasoning and path query
|
||||
|
||||
### 5. MemoryExtractionEngine 记忆提取引擎模块 (4个)
|
||||
- `memoryExtractionEngine.coreEntitiesAfterDedup` - Core entities after deduplication
|
||||
- `memoryExtractionEngine.extractRelationalTriples` - Extracted relational triples (partial)
|
||||
- `memoryExtractionEngine.extractRelationalTriplesDesc` - There are a total of {{count}} segments with clear semantic boundaries
|
||||
- `memoryExtractionEngine.theEffectOfEntityDisambiguationLLMDriven` - The effect of entity disambiguation (LLM driven)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 建议
|
||||
|
||||
### 优先级 1 - 核心功能模块(需要立即补充)
|
||||
1. **Role 角色管理** - 完整模块缺失(15个键)
|
||||
2. **Tenant 租户管理** - 完整模块缺失(20个键)
|
||||
3. **Product 产品管理** - 完整模块缺失(13个键)
|
||||
4. **User 用户管理扩展** - 批量导入功能缺失(13个键)
|
||||
|
||||
### 优先级 2 - 功能增强(建议补充)
|
||||
1. **Application 应用模块** - 多代理相关功能(15个键)
|
||||
2. **Space 空间模块** - 存储类型配置(5个键)
|
||||
3. **MemoryExtractionEngine** - 实体去重相关(4个键)
|
||||
|
||||
### 优先级 3 - 演示/测试功能(可选)
|
||||
1. **Home/Workflow/NotFound** - 演示页面(30个键)
|
||||
2. **通用计数器功能** - 测试功能(5个键)
|
||||
|
||||
---
|
||||
|
||||
## 📝 下一步行动
|
||||
|
||||
1. **补充英文翻译**: 优先补充 Role、Tenant、Product、User 模块的英文翻译
|
||||
2. **补充中文翻译**: 补充 Application、Space、MemoryExtractionEngine 模块的中文翻译
|
||||
3. **清理无用翻译**: 如果 Home/Workflow 等演示功能不再使用,可以考虑从中文文件中移除
|
||||
4. **建立翻译规范**: 建议建立翻译键的命名规范和审查流程,避免未来出现遗漏
|
||||
|
||||
72
web/package.json
Normal file
72
web/package.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "memory-bear-font-end",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/modifiers": "^9.0.0",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"antd": "^5.27.4",
|
||||
"axios": "^1.12.2",
|
||||
"clsx": "^2.1.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.18",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"i18next": "^25.6.0",
|
||||
"mermaid": "^11.12.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^15.0.0",
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-router-dom": "^6.22.0",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
"reactflow": "^11.11.4",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"zustand": "^5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@tailwindcss/postcss": "^4.1.14",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/node": "^24.6.0",
|
||||
"@types/react": "^18.2.0",
|
||||
"@types/react-dom": "^18.2.0",
|
||||
"@types/react-i18next": "^7.8.3",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.22",
|
||||
"globals": "^16.4.0",
|
||||
"less": "^4.4.2",
|
||||
"terser": "^5.44.0",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.45.0",
|
||||
"unplugin-auto-import": "^20.2.0",
|
||||
"unplugin-vue-components": "^29.1.0",
|
||||
"vite": "npm:rolldown-vite@7.1.14"
|
||||
},
|
||||
"overrides": {
|
||||
"vite": "npm:rolldown-vite@7.1.14"
|
||||
}
|
||||
}
|
||||
10
web/public/auto-imports.d.ts
vendored
10
web/public/auto-imports.d.ts
vendored
@@ -6,22 +6,31 @@
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const Activity: typeof import('react').Activity
|
||||
const Fragment: typeof import('react').Fragment
|
||||
const Link: typeof import('react-router-dom').Link
|
||||
const NavLink: typeof import('react-router-dom').NavLink
|
||||
const Navigate: typeof import('react-router-dom').Navigate
|
||||
const Outlet: typeof import('react-router-dom').Outlet
|
||||
const Route: typeof import('react-router-dom').Route
|
||||
const Routes: typeof import('react-router-dom').Routes
|
||||
const Suspense: typeof import('react').Suspense
|
||||
const cache: typeof import('react').cache
|
||||
const cacheSignal: typeof import('react').cacheSignal
|
||||
const createContext: typeof import('react').createContext
|
||||
const createRef: typeof import('react').createRef
|
||||
const forwardRef: typeof import('react').forwardRef
|
||||
const lazy: typeof import('react').lazy
|
||||
const memo: typeof import('react').memo
|
||||
const startTransition: typeof import('react').startTransition
|
||||
const use: typeof import('react').use
|
||||
const useActionState: typeof import('react').useActionState
|
||||
const useCallback: typeof import('react').useCallback
|
||||
const useContext: typeof import('react').useContext
|
||||
const useDebugValue: typeof import('react').useDebugValue
|
||||
const useDeferredValue: typeof import('react').useDeferredValue
|
||||
const useEffect: typeof import('react').useEffect
|
||||
const useEffectEvent: typeof import('react').useEffectEvent
|
||||
const useHref: typeof import('react-router-dom').useHref
|
||||
const useId: typeof import('react').useId
|
||||
const useImperativeHandle: typeof import('react').useImperativeHandle
|
||||
@@ -33,6 +42,7 @@ declare global {
|
||||
const useMemo: typeof import('react').useMemo
|
||||
const useNavigate: typeof import('react-router-dom').useNavigate
|
||||
const useNavigationType: typeof import('react-router-dom').useNavigationType
|
||||
const useOptimistic: typeof import('react').useOptimistic
|
||||
const useOutlet: typeof import('react-router-dom').useOutlet
|
||||
const useOutletContext: typeof import('react-router-dom').useOutletContext
|
||||
const useParams: typeof import('react-router-dom').useParams
|
||||
|
||||
@@ -140,7 +140,8 @@ const TableComponent = forwardRef<TableRef, TableComponentProps>(({
|
||||
|
||||
const config: { x?: number | string | true; y?: number | string } = {};
|
||||
|
||||
if (scrollX !== undefined) {
|
||||
// 只有在有数据时才应用横向滚动
|
||||
if (scrollX !== undefined && data.length > 0) {
|
||||
config.x = scrollX;
|
||||
} else if (isScroll) {
|
||||
config.x = 'max-content';
|
||||
|
||||
@@ -403,6 +403,7 @@ export const en = {
|
||||
apiKeyName: 'API Key Name',
|
||||
},
|
||||
knowledgeBase: {
|
||||
selectSpace: 'Please select a workspace.',
|
||||
preview:'Preview',
|
||||
pleaseUploadFileFirst: 'Please upload file first',
|
||||
shareSuccess: 'Share successfully',
|
||||
|
||||
@@ -35,6 +35,7 @@ export const zh = {
|
||||
userMemoryDetail: '用户记忆详情',
|
||||
},
|
||||
knowledgeBase: {
|
||||
selectSpace: '请选择空间',
|
||||
preview:'预览',
|
||||
pleaseUploadFileFirst: '请先上传文件',
|
||||
shareSuccess: '分享成功',
|
||||
|
||||
46
web/src/routes/routes.json
Normal file
46
web/src/routes/routes.json
Normal file
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"element": "AuthLayout",
|
||||
"children": [
|
||||
{ "path": "/user-management", "element": "UserManagement" },
|
||||
{ "path": "/model", "element": "ModelManagement" },
|
||||
{ "path": "/space", "element": "SpaceManagement" },
|
||||
{ "path": "/no-permission", "element": "NoPermission" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"element": "AuthSpaceLayout",
|
||||
"children": [
|
||||
{ "path": "/", "element": "Home" },
|
||||
{ "path": "/user-memory", "element": "UserMemory" },
|
||||
{ "path": "/user-memory/:id", "element": "UserMemoryDetail" },
|
||||
{ "path": "/member", "element": "MemberManagement" },
|
||||
{ "path": "/memory", "element": "MemoryManagement" },
|
||||
{ "path": "/forgetting-engine/:id", "element": "ForgettingEngine" },
|
||||
{ "path": "/memory-extraction-engine/:id", "element": "MemoryExtractionEngine" },
|
||||
{ "path": "/application", "element": "ApplicationManagement" },
|
||||
{ "path": "/memory-conversation", "element": "MemoryConversation" },
|
||||
{ "path": "/knowledge-base", "element": "KnowledgeBase" },
|
||||
{ "path": "/knowledge-base/:knowledgeBaseId/private", "element": "Private" },
|
||||
{ "path": "/knowledge-base/:knowledgeBaseId/share", "element": "Share" },
|
||||
{ "path": "/knowledge-base/:knowledgeBaseId/create-dataset", "element": "CreateDataset" },
|
||||
{ "path": "/knowledge-base/:knowledgeBaseId/DocumentDetails", "element": "DocumentDetails" },
|
||||
{ "path": "/no-permission", "element": "NoPermission" },
|
||||
{ "path": "/*", "element": "NotFound" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"element": "BasicLayout",
|
||||
"children": [
|
||||
{ "path": "/application/config/:id", "element": "ApplicationConfig" },
|
||||
{ "path": "/conversation/:token", "element": "Conversation" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"element": "LoginLayout",
|
||||
"children": [
|
||||
{ "path": "/login", "element": "Login" },
|
||||
{ "path": "/invite-register/:token", "element": "InviteRegister" }
|
||||
]
|
||||
}
|
||||
]
|
||||
248
web/src/store/menu.json
Normal file
248
web/src/store/menu.json
Normal file
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"manage": [
|
||||
{
|
||||
"id": 1,
|
||||
"parent": 0,
|
||||
"code": "model",
|
||||
"label": "模型管理",
|
||||
"i18nKey": "menu.modelManagement",
|
||||
"path": "/model",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"parent": 0,
|
||||
"code": "space",
|
||||
"label": "空间管理",
|
||||
"i18nKey": "menu.spaceManagement",
|
||||
"path": "/space",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": []
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"parent": 0,
|
||||
"code": "user",
|
||||
"label": "用户管理",
|
||||
"i18nKey": "menu.userManagement",
|
||||
"path": "/user-management",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 2,
|
||||
"menuDesc": "管理系统用户信息",
|
||||
"subs": null
|
||||
}
|
||||
],
|
||||
"space": [
|
||||
{
|
||||
"id": 4,
|
||||
"parent": 0,
|
||||
"code": "dashboard",
|
||||
"label": "记忆看板",
|
||||
"i18nKey": "menu.home",
|
||||
"path": "/",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"parent": 0,
|
||||
"code": "application",
|
||||
"label": "应用管理",
|
||||
"i18nKey": "menu.applicationManagement",
|
||||
"path": "/application",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"parent": 0,
|
||||
"code": "knowledge",
|
||||
"label": "知识库",
|
||||
"i18nKey": "menu.knowledgeManagement",
|
||||
"path": "/knowledge-base",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": [
|
||||
{
|
||||
"id": 61,
|
||||
"parent": 6,
|
||||
"code": "knowledgePrivate",
|
||||
"label": "Private",
|
||||
"i18nKey": "menu.knowledgePrivate",
|
||||
"path": "/knowledge-base/:knowledgeBaseId/private",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 62,
|
||||
"parent": 6,
|
||||
"code": "knowledgeShare",
|
||||
"label": "Share",
|
||||
"i18nKey": "menu.knowledgeShare",
|
||||
"path": "/knowledge-base/:knowledgeBaseId/share",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 63,
|
||||
"parent": 6,
|
||||
"code": "knowledgeCreateDataset",
|
||||
"label": "CreateDataset",
|
||||
"i18nKey": "menu.knowledgeCreateDataset",
|
||||
"path": "/knowledge-base/:knowledgeBaseId/create-dataset",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 64,
|
||||
"parent": 6,
|
||||
"code": "knowledgeDocumentDetails",
|
||||
"label": "DocumentDetails",
|
||||
"i18nKey": "menu.knowledgeDocumentDetails",
|
||||
"path": "/knowledge-base/:knowledgeBaseId/DocumentDetails",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"parent": 0,
|
||||
"code": "memory",
|
||||
"label": "记忆管理",
|
||||
"i18nKey": "menu.memoryManagement",
|
||||
"path": "/memory",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": [
|
||||
{
|
||||
"id": 71,
|
||||
"parent": 7,
|
||||
"code": "forgettingEngine",
|
||||
"label": "遗忘引擎",
|
||||
"i18nKey": "menu.forgettingEngine",
|
||||
"path": "/forgetting-engine/:id",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 72,
|
||||
"parent": 7,
|
||||
"code": "memoryExtractionEngine",
|
||||
"label": "记忆萃取引擎",
|
||||
"i18nKey": "menu.memoryExtractionEngine",
|
||||
"path": "/memory-extraction-engine/:id",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"subs": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"parent": 0,
|
||||
"code": "userMemory",
|
||||
"label": "",
|
||||
"i18nKey": "menu.userMemory",
|
||||
"path": "/user-memory",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 1,
|
||||
"menuDesc": "管理用户记忆",
|
||||
"subs": [
|
||||
{
|
||||
"id": 81,
|
||||
"parent": 8,
|
||||
"code": "userMemoryDetail",
|
||||
"label": "记忆详情",
|
||||
"i18nKey": "menu.userMemoryDetail",
|
||||
"path": "/user-memory/:id",
|
||||
"enable": true,
|
||||
"display": false,
|
||||
"level": 2,
|
||||
"sort": 0,
|
||||
"subs": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"parent": 0,
|
||||
"code": "member",
|
||||
"label": "成员管理",
|
||||
"i18nKey": "menu.memberManagement",
|
||||
"path": "/member",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"parent": 0,
|
||||
"code": "memoryConversation",
|
||||
"label": "记忆验证",
|
||||
"i18nKey": "menu.memoryConversation",
|
||||
"path": "/memory-conversation",
|
||||
"enable": true,
|
||||
"display": true,
|
||||
"level": 1,
|
||||
"sort": 0,
|
||||
"icon": null,
|
||||
"iconActive": null,
|
||||
"subs": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -12,17 +12,17 @@ export interface MenuItem {
|
||||
display: boolean;
|
||||
level: number;
|
||||
sort: number;
|
||||
icon: string | null;
|
||||
iconActive: string | null;
|
||||
menuDesc: string | null;
|
||||
deleted: string | null;
|
||||
updateTime: number;
|
||||
new_: string | null;
|
||||
keepAlive: boolean;
|
||||
master: string | null;
|
||||
disposable: boolean;
|
||||
appSystem: string | null;
|
||||
subs: MenuItem[];
|
||||
icon?: string | null;
|
||||
iconActive?: string | null;
|
||||
menuDesc?: string | null;
|
||||
deleted?: string | null;
|
||||
updateTime?: number;
|
||||
new_?: string | null;
|
||||
keepAlive?: boolean;
|
||||
master?: string | null;
|
||||
disposable?: boolean;
|
||||
appSystem?: string | null;
|
||||
subs: MenuItem[] | null;
|
||||
}
|
||||
interface MenuState {
|
||||
collapsed: boolean;
|
||||
@@ -31,6 +31,7 @@ interface MenuState {
|
||||
allBreadcrumbs: Record<'space' | 'manage' | string, MenuItem[]>;
|
||||
loadMenus: (source: 'space' | 'manage') => void;
|
||||
updateBreadcrumbs: (keyPath: string[], source: 'space' | 'manage') => void;
|
||||
setCustomBreadcrumbs: (breadcrumbs: MenuItem[], source: 'space' | 'manage') => void;
|
||||
}
|
||||
|
||||
const initBreadcrumbs = localStorage.getItem('breadcrumbs') || '[]'
|
||||
@@ -73,4 +74,9 @@ export const useMenu = create<MenuState>((set, get) => ({
|
||||
set({ allBreadcrumbs })
|
||||
localStorage.setItem('breadcrumbs', JSON.stringify(allBreadcrumbs))
|
||||
},
|
||||
setCustomBreadcrumbs: (breadcrumbs, source) => {
|
||||
const allBreadcrumbs = { ...get().allBreadcrumbs, [source]: breadcrumbs }
|
||||
set({ allBreadcrumbs })
|
||||
localStorage.setItem('breadcrumbs', JSON.stringify(allBreadcrumbs))
|
||||
},
|
||||
}))
|
||||
@@ -145,6 +145,7 @@ const CreateDataset = () => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
debugger
|
||||
|
||||
// 显示确认弹框
|
||||
confirm({
|
||||
@@ -195,11 +196,12 @@ const CreateDataset = () => {
|
||||
title: t('common.deleteWarning'),
|
||||
content: t('common.deleteWarningContent', { content: record.name }),
|
||||
onOk: async () => {
|
||||
// TODO: 实现删除逻辑
|
||||
const response = await deleteDocument(record.id);
|
||||
await deleteDocument(record.id);
|
||||
|
||||
// 删除成功,刷新列表
|
||||
// messageApi.success(t('common.deleteSuccess'));
|
||||
// 删除成功,从 rechunkFileIds 中移除该 id
|
||||
setRechunkFileIds((prev) => prev.filter((id) => id !== record.id));
|
||||
|
||||
// 刷新列表
|
||||
messageApi.success(t('common.deleteSuccess'));
|
||||
tableRef.current?.loadData();
|
||||
|
||||
@@ -560,6 +562,7 @@ const CreateDataset = () => {
|
||||
{current === 2 && (
|
||||
<Spin spinning={pollingLoading} tip={t('knowledgeBase.processingDocuments') || '正在处理文档...'}>
|
||||
<div className='rb:text-sm rb:text-gray-500 rb:mt-4 rb:h-[calc(100%-160px)] rb:overflow-y-auto'>
|
||||
{rechunkFileIds.length > 0 ? (
|
||||
<Table
|
||||
ref={tableRef}
|
||||
apiUrl={`/documents/${knowledgeBaseId}/${parentId}/documents`}
|
||||
@@ -569,6 +572,14 @@ const CreateDataset = () => {
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
/>
|
||||
) : (
|
||||
<Table
|
||||
ref={tableRef}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
initialData={[]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
)}
|
||||
|
||||
@@ -11,10 +11,6 @@ import type { AnyObject } from 'antd/es/_util/type';
|
||||
import { MoreOutlined } from '@ant-design/icons';
|
||||
import folderIcon from '@/assets/images/knowledgeBase/folder.png';
|
||||
import textIcon from '@/assets/images/knowledgeBase/text.png';
|
||||
import imageIcon from '@/assets/images/knowledgeBase/image.png';
|
||||
import blankIcon from '@/assets/images/knowledgeBase/blankDocument.png';
|
||||
import templateIcon from '@/assets/images/knowledgeBase/template.png';
|
||||
import backupIcon from '@/assets/images/knowledgeBase/backup.png';
|
||||
import editIcon from '@/assets/images/knowledgeBase/edit.png';
|
||||
import { getKnowledgeBaseDetail, deleteDocument, downloadFile, updateKnowledgeBase } from '../service';
|
||||
import type {
|
||||
@@ -35,6 +31,7 @@ import CreateDatasetModal from '../components/CreateDatasetModal';
|
||||
import CreateImageDataset from '../components/CreateImageDataset';
|
||||
import FolderTree, { type TreeNodeData } from '../components/FolderTree';
|
||||
import { formatDateTime } from '@/utils/format';
|
||||
import { useMenu } from '@/store/menu';
|
||||
import './Private.css'
|
||||
const { confirm } = Modal
|
||||
// 树节点数据类型
|
||||
@@ -57,7 +54,6 @@ const Private: FC = () => {
|
||||
kb_id:knowledgeBaseId ?? '',
|
||||
parent_id:parentId ?? ''
|
||||
});
|
||||
const [keywords, setKeywords] = useState<string>('');
|
||||
const [query, setQuery] = useState<Record<string, unknown>>({
|
||||
orderby: 'created_at',
|
||||
desc: true,
|
||||
@@ -66,6 +62,8 @@ const Private: FC = () => {
|
||||
const shareModalRef = useRef<ShareModalRef>(null);
|
||||
const datasetModalRef = useRef<CreateDatasetModalRef>(null);
|
||||
const [folderTreeRefreshKey, setFolderTreeRefreshKey] = useState(0);
|
||||
const { allBreadcrumbs, setCustomBreadcrumbs } = useMenu();
|
||||
const [folderPath, setFolderPath] = useState<Array<{ id: string; name: string }>>([]);
|
||||
useEffect(() => {
|
||||
if (knowledgeBaseId) {
|
||||
let url = `/documents/${knowledgeBaseId}/${parentId}/documents`;
|
||||
@@ -74,6 +72,13 @@ const Private: FC = () => {
|
||||
}
|
||||
}, [knowledgeBaseId]);
|
||||
|
||||
// 更新面包屑
|
||||
useEffect(() => {
|
||||
if (knowledgeBase) {
|
||||
updateBreadcrumbs();
|
||||
}
|
||||
}, [knowledgeBase, folderPath]);
|
||||
|
||||
// 监听 tableApi 变化,自动刷新表格数据
|
||||
useEffect(() => {
|
||||
if (tableApi) {
|
||||
@@ -95,17 +100,82 @@ const Private: FC = () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await getKnowledgeBaseDetail(id);
|
||||
setKnowledgeBase(res.data || res);
|
||||
// 将 KnowledgeBase 转换为 KnowledgeBaseListItem
|
||||
const listItem = res as unknown as KnowledgeBaseListItem;
|
||||
setKnowledgeBase(listItem);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 更新面包屑,包含知识库名称和文件夹路径
|
||||
const updateBreadcrumbs = () => {
|
||||
if (!knowledgeBase) return;
|
||||
|
||||
const baseBreadcrumbs = allBreadcrumbs['space'] || [];
|
||||
// 只保留知识库菜单项之前的面包屑
|
||||
const knowledgeBaseMenuIndex = baseBreadcrumbs.findIndex(item => item.path === '/knowledge-base');
|
||||
const filteredBaseBreadcrumbs = knowledgeBaseMenuIndex >= 0
|
||||
? baseBreadcrumbs.slice(0, knowledgeBaseMenuIndex + 1)
|
||||
: baseBreadcrumbs;
|
||||
|
||||
const customBreadcrumbs = [
|
||||
...filteredBaseBreadcrumbs,
|
||||
{
|
||||
id: 0,
|
||||
parent: 0,
|
||||
code: null,
|
||||
label: knowledgeBase.name,
|
||||
i18nKey: null,
|
||||
path: null,
|
||||
enable: true,
|
||||
display: true,
|
||||
level: 0,
|
||||
sort: 0,
|
||||
icon: null,
|
||||
iconActive: null,
|
||||
menuDesc: null,
|
||||
deleted: null,
|
||||
updateTime: 0,
|
||||
new_: null,
|
||||
keepAlive: false,
|
||||
master: null,
|
||||
disposable: false,
|
||||
appSystem: null,
|
||||
subs: [],
|
||||
},
|
||||
...folderPath.map((folder) => ({
|
||||
id: 0,
|
||||
parent: 0,
|
||||
code: null,
|
||||
label: folder.name,
|
||||
i18nKey: null,
|
||||
path: null,
|
||||
enable: true,
|
||||
display: true,
|
||||
level: 0,
|
||||
sort: 0,
|
||||
icon: null,
|
||||
iconActive: null,
|
||||
menuDesc: null,
|
||||
deleted: null,
|
||||
updateTime: 0,
|
||||
new_: null,
|
||||
keepAlive: false,
|
||||
master: null,
|
||||
disposable: false,
|
||||
appSystem: null,
|
||||
subs: [],
|
||||
})),
|
||||
];
|
||||
|
||||
setCustomBreadcrumbs(customBreadcrumbs, 'space');
|
||||
};
|
||||
|
||||
// 处理树节点选择
|
||||
const onSelect = (selectedKeys: React.Key[], info: any) => {
|
||||
const onSelect = (selectedKeys: React.Key[]) => {
|
||||
if (!selectedKeys.length) return;
|
||||
if (!folder) return;
|
||||
const node = info.node as TreeNodeData;
|
||||
const f = {
|
||||
...folder,
|
||||
parent_id: String(selectedKeys[0]),
|
||||
@@ -114,17 +184,16 @@ const Private: FC = () => {
|
||||
setTableApi(url);
|
||||
setParentId(String(selectedKeys[0]))
|
||||
setFolder(f)
|
||||
// 根据节点类型执行不同操作
|
||||
if (node.type === 'folder') {
|
||||
};
|
||||
|
||||
// 文件夹:展开/收起
|
||||
} else if (node.type === 'text' || node.type === 'image' || node.type === 'dataset') {
|
||||
// 文件:打开详情
|
||||
}
|
||||
// 处理文件夹路径变化
|
||||
const handleFolderPathChange = (path: Array<{ id: string; name: string }>) => {
|
||||
setFolderPath(path);
|
||||
};
|
||||
|
||||
// 处理树节点展开
|
||||
const onExpand = (expandedKeys: React.Key[], info: any) => {
|
||||
const onExpand = (_expandedKeys: React.Key[], _info: any) => {
|
||||
// 展开节点时不需要特殊处理
|
||||
};
|
||||
// create / import list
|
||||
const createItems: MenuProps['items'] = [
|
||||
@@ -190,10 +259,7 @@ const Private: FC = () => {
|
||||
// },
|
||||
|
||||
];
|
||||
//
|
||||
const handleCreate = (type: string) => {
|
||||
console.log('create', type);
|
||||
}
|
||||
|
||||
// 处理开关
|
||||
const onChange = (checked: boolean) => {
|
||||
updateKnowledgeBase(knowledgeBaseId || '', {
|
||||
@@ -348,8 +414,7 @@ const Private: FC = () => {
|
||||
title: t('knowledgeBase.status'),
|
||||
dataIndex: 'progress',
|
||||
key: 'progress',
|
||||
render: (value: string | number, record: AnyObject) => {
|
||||
|
||||
render: (value: string | number) => {
|
||||
return (
|
||||
<span className="rb:text-xs rb:border rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded rb:items-center rb:text-[#212332] rb:py-1 rb:px-2">
|
||||
<span
|
||||
@@ -445,6 +510,7 @@ const Private: FC = () => {
|
||||
knowledgeBaseId={knowledgeBaseId ?? ''}
|
||||
refreshKey={folderTreeRefreshKey}
|
||||
onRootLoad={handleRootTreeLoad}
|
||||
onFolderPathChange={handleFolderPathChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -58,6 +58,7 @@ interface FolderTreeProps {
|
||||
style?: CSSProperties;
|
||||
refreshKey?: number;
|
||||
onRootLoad?: (nodes: TreeNodeData[] | null) => void;
|
||||
onFolderPathChange?: (path: Array<{ id: string; name: string }>) => void;
|
||||
}
|
||||
|
||||
const renderIcon = (icon?: string) => {
|
||||
@@ -271,6 +272,7 @@ const FolderTree: FC<FolderTreeProps> = ({
|
||||
style,
|
||||
refreshKey = 0,
|
||||
onRootLoad,
|
||||
onFolderPathChange,
|
||||
}) => {
|
||||
const [treeData, setTreeData] = useState<TreeNodeData[]>([]);
|
||||
|
||||
@@ -347,6 +349,42 @@ const FolderTree: FC<FolderTreeProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
// 查找节点路径的辅助函数
|
||||
const findNodePath = (nodes: TreeNodeData[], targetKey: Key, currentPath: Array<{ id: string; name: string }> = []): Array<{ id: string; name: string }> | null => {
|
||||
for (const node of nodes) {
|
||||
const newPath = [...currentPath, { id: String(node.key), name: String(node.title) }];
|
||||
|
||||
if (node.key === targetKey) {
|
||||
return newPath;
|
||||
}
|
||||
|
||||
if (node.children) {
|
||||
const found = findNodePath(node.children, targetKey, newPath);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// 处理选择事件,计算并传递路径
|
||||
const handleSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
|
||||
if (selectedKeys.length > 0) {
|
||||
const path = findNodePath(treeData, selectedKeys[0]);
|
||||
if (path && onFolderPathChange) {
|
||||
onFolderPathChange(path);
|
||||
}
|
||||
} else if (onFolderPathChange) {
|
||||
onFolderPathChange([]);
|
||||
}
|
||||
|
||||
// 调用原始的 onSelect 回调
|
||||
if (onSelect) {
|
||||
onSelect(selectedKeys, info);
|
||||
}
|
||||
};
|
||||
|
||||
const treeNodes = useMemo(() => transformTreeData(treeData), [treeData]);
|
||||
|
||||
return (
|
||||
@@ -354,7 +392,7 @@ const FolderTree: FC<FolderTreeProps> = ({
|
||||
multiple={multiple}
|
||||
className={className}
|
||||
style={style}
|
||||
onSelect={onSelect}
|
||||
onSelect={handleSelect}
|
||||
onExpand={onExpand}
|
||||
loadData={onLoadData}
|
||||
treeData={treeNodes}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* @Author: yujiangping
|
||||
* @Date: 2025-11-10 18:52:55
|
||||
* @LastEditors: yujiangping
|
||||
* @LastEditTime: 2025-11-25 17:46:36
|
||||
* @LastEditTime: 2025-12-03 18:44:58
|
||||
*/
|
||||
import { forwardRef, useImperativeHandle, useState } from 'react';
|
||||
import { Switch } from 'antd';
|
||||
@@ -24,7 +24,7 @@ const ShareModal = forwardRef<ShareModalRef,ShareModalRefProps>(({ handleShare:
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [curIndex, setCurIndex] = useState(9999);
|
||||
const [curIndex, setCurIndex] = useState(-1);
|
||||
const [kbId, setKbId] = useState<string>('');
|
||||
const [spaceIds, setSpaceIds] = useState<string>('');
|
||||
const [knowledgeBase, setKnowledgeBase] = useState<KnowledgeBase | null>(null);
|
||||
@@ -32,7 +32,7 @@ const ShareModal = forwardRef<ShareModalRef,ShareModalRefProps>(({ handleShare:
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
const handleClose = () => {
|
||||
setCurIndex(9999);
|
||||
setCurIndex(-1);
|
||||
setLoading(false)
|
||||
setVisible(false);
|
||||
};
|
||||
@@ -53,8 +53,13 @@ const ShareModal = forwardRef<ShareModalRef,ShareModalRefProps>(({ handleShare:
|
||||
|
||||
// 获取所有 checked 为 true 的数据
|
||||
const checkedItems = spaceList.filter(item => item.is_active);
|
||||
debugger
|
||||
// 获取当前选中的项(curIndex 对应的数据)
|
||||
const selectedItem = curIndex !== 9999 ? spaceList[curIndex] : null;
|
||||
const selectedItem = curIndex !== -1 ? spaceList[curIndex] : null;
|
||||
if(!selectedItem){
|
||||
messageApi.error(t('knowledgeBase.selectSpace'));
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
source_kb_id: kbId ?? '',
|
||||
target_workspace_id: selectedItem?.id ?? '',
|
||||
|
||||
33
web/tsconfig.app.json
Normal file
33
web/tsconfig.app.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"types": ["vite/client"],
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["**/*copy*"]
|
||||
}
|
||||
10
web/tsconfig.json
Normal file
10
web/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"files": [],
|
||||
"compilerOptions": {
|
||||
"ignoreDeprecations": "5.0"
|
||||
},
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
26
web/tsconfig.node.json
Normal file
26
web/tsconfig.node.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2023",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"types": ["node"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user