diff --git a/COMMIT_DAY1.txt b/COMMIT_DAY1.txt index ad7094ab..51f9eafa 100644 --- a/COMMIT_DAY1.txt +++ b/COMMIT_DAY1.txt @@ -43,5 +43,7 @@ Status: Day 1 complete (11/11 tasks), ready for Day 2 + + diff --git a/DC模块代码恢复指南.md b/DC模块代码恢复指南.md index 850602bb..8d009392 100644 --- a/DC模块代码恢复指南.md +++ b/DC模块代码恢复指南.md @@ -272,6 +272,8 @@ + + diff --git a/SAE_WECHAT_MP_DEPLOY_STEPS.md b/SAE_WECHAT_MP_DEPLOY_STEPS.md index 146c1373..f758b02c 100644 --- a/SAE_WECHAT_MP_DEPLOY_STEPS.md +++ b/SAE_WECHAT_MP_DEPLOY_STEPS.md @@ -221,3 +221,5 @@ https://iit.xunzhengyixue.com/api/v1/iit/health + + diff --git a/backend/DEPLOY_TO_SAE_FOR_WECHAT_MP.md b/backend/DEPLOY_TO_SAE_FOR_WECHAT_MP.md index 24ac1790..bcf63225 100644 --- a/backend/DEPLOY_TO_SAE_FOR_WECHAT_MP.md +++ b/backend/DEPLOY_TO_SAE_FOR_WECHAT_MP.md @@ -150,3 +150,5 @@ https://iit.xunzhengyixue.com/api/v1/iit/health + + diff --git a/backend/RESTART_SERVER_NOW.md b/backend/RESTART_SERVER_NOW.md index 2f666841..5d2d662f 100644 --- a/backend/RESTART_SERVER_NOW.md +++ b/backend/RESTART_SERVER_NOW.md @@ -51,3 +51,5 @@ + + diff --git a/backend/WECHAT_MP_CONFIG_READY.md b/backend/WECHAT_MP_CONFIG_READY.md index 11eed4dc..4b52169e 100644 --- a/backend/WECHAT_MP_CONFIG_READY.md +++ b/backend/WECHAT_MP_CONFIG_READY.md @@ -311,3 +311,5 @@ npx tsx src/modules/iit-manager/test-patient-wechat-url-verify.ts + + diff --git a/backend/WECHAT_MP_QUICK_FIX.md b/backend/WECHAT_MP_QUICK_FIX.md index 80e4531f..32249f9f 100644 --- a/backend/WECHAT_MP_QUICK_FIX.md +++ b/backend/WECHAT_MP_QUICK_FIX.md @@ -173,3 +173,5 @@ npm run dev + + diff --git a/backend/check_db.ts b/backend/check_db.ts index a00702d6..36b2d2e3 100644 --- a/backend/check_db.ts +++ b/backend/check_db.ts @@ -50,3 +50,5 @@ main() + + diff --git a/backend/check_db_data.ts b/backend/check_db_data.ts index 5a2b125c..24b2750b 100644 --- a/backend/check_db_data.ts +++ b/backend/check_db_data.ts @@ -44,3 +44,5 @@ main() + + diff --git a/backend/check_iit.ts b/backend/check_iit.ts index 2748a44e..3b38420f 100644 --- a/backend/check_iit.ts +++ b/backend/check_iit.ts @@ -39,3 +39,5 @@ main() + + diff --git a/backend/check_iit_asl_data.ts b/backend/check_iit_asl_data.ts index 195a480b..496c7a00 100644 --- a/backend/check_iit_asl_data.ts +++ b/backend/check_iit_asl_data.ts @@ -71,3 +71,5 @@ main() + + diff --git a/backend/check_queue_table.ts b/backend/check_queue_table.ts index e1d3364d..d4ca33c8 100644 --- a/backend/check_queue_table.ts +++ b/backend/check_queue_table.ts @@ -34,3 +34,5 @@ main() + + diff --git a/backend/check_rvw_issue.ts b/backend/check_rvw_issue.ts index 2318019f..53aa11eb 100644 --- a/backend/check_rvw_issue.ts +++ b/backend/check_rvw_issue.ts @@ -75,3 +75,5 @@ main() + + diff --git a/backend/check_tables.ts b/backend/check_tables.ts index 26989c38..e553e850 100644 --- a/backend/check_tables.ts +++ b/backend/check_tables.ts @@ -22,3 +22,5 @@ main() + + diff --git a/backend/compare_db.ts b/backend/compare_db.ts index 3cd1eea3..c487daf3 100644 --- a/backend/compare_db.ts +++ b/backend/compare_db.ts @@ -110,3 +110,5 @@ main() + + diff --git a/backend/compare_dc_asl.ts b/backend/compare_dc_asl.ts index 404eb0dc..627c96ee 100644 --- a/backend/compare_dc_asl.ts +++ b/backend/compare_dc_asl.ts @@ -81,3 +81,5 @@ main() + + diff --git a/backend/compare_pkb_aia_rvw.ts b/backend/compare_pkb_aia_rvw.ts index ac637688..53370974 100644 --- a/backend/compare_pkb_aia_rvw.ts +++ b/backend/compare_pkb_aia_rvw.ts @@ -67,3 +67,5 @@ main() + + diff --git a/backend/compare_schema_db.ts b/backend/compare_schema_db.ts index b8e16b54..fc3289c3 100644 --- a/backend/compare_schema_db.ts +++ b/backend/compare_schema_db.ts @@ -109,3 +109,5 @@ main() + + diff --git a/backend/create_mock_user.sql b/backend/create_mock_user.sql index 08e92690..06b62c38 100644 --- a/backend/create_mock_user.sql +++ b/backend/create_mock_user.sql @@ -20,3 +20,5 @@ ON CONFLICT (id) DO NOTHING; + + diff --git a/backend/create_mock_user_platform.sql b/backend/create_mock_user_platform.sql index 1ef10257..eb374090 100644 --- a/backend/create_mock_user_platform.sql +++ b/backend/create_mock_user_platform.sql @@ -52,3 +52,5 @@ ON CONFLICT (id) DO NOTHING; + + diff --git a/backend/migrations/add_data_stats_to_tool_c_session.sql b/backend/migrations/add_data_stats_to_tool_c_session.sql index 9ea35df3..916e910b 100644 --- a/backend/migrations/add_data_stats_to_tool_c_session.sql +++ b/backend/migrations/add_data_stats_to_tool_c_session.sql @@ -67,6 +67,8 @@ WHERE table_schema = 'dc_schema' + + diff --git a/backend/prisma/manual-migrations/001_add_postgres_cache_and_checkpoint.sql b/backend/prisma/manual-migrations/001_add_postgres_cache_and_checkpoint.sql index 720b1024..b58e8291 100644 --- a/backend/prisma/manual-migrations/001_add_postgres_cache_and_checkpoint.sql +++ b/backend/prisma/manual-migrations/001_add_postgres_cache_and_checkpoint.sql @@ -105,6 +105,8 @@ ORDER BY ordinal_position; + + diff --git a/backend/prisma/manual-migrations/run-migration-002.ts b/backend/prisma/manual-migrations/run-migration-002.ts index ecb5f34a..9cd27194 100644 --- a/backend/prisma/manual-migrations/run-migration-002.ts +++ b/backend/prisma/manual-migrations/run-migration-002.ts @@ -118,6 +118,8 @@ runMigration() + + diff --git a/backend/prisma/migrations/20251208_add_column_mapping/migration.sql b/backend/prisma/migrations/20251208_add_column_mapping/migration.sql index 972ae4ea..4d7cfb24 100644 --- a/backend/prisma/migrations/20251208_add_column_mapping/migration.sql +++ b/backend/prisma/migrations/20251208_add_column_mapping/migration.sql @@ -52,6 +52,8 @@ COMMENT ON COLUMN "dc_schema"."dc_tool_c_sessions"."column_mapping" IS '列名 + + diff --git a/backend/prisma/migrations/create_tool_c_session.sql b/backend/prisma/migrations/create_tool_c_session.sql index fd6b5004..f1fc08f3 100644 --- a/backend/prisma/migrations/create_tool_c_session.sql +++ b/backend/prisma/migrations/create_tool_c_session.sql @@ -79,6 +79,8 @@ COMMENT ON COLUMN dc_schema.dc_tool_c_sessions.expires_at IS '过期时间(创 + + diff --git a/backend/rebuild-and-push.ps1 b/backend/rebuild-and-push.ps1 index 2f50c2da..86fb15b5 100644 --- a/backend/rebuild-and-push.ps1 +++ b/backend/rebuild-and-push.ps1 @@ -119,6 +119,8 @@ Write-Host "" + + diff --git a/backend/recover-code-from-cursor-db.js b/backend/recover-code-from-cursor-db.js index 3b6f9d63..77a42b61 100644 --- a/backend/recover-code-from-cursor-db.js +++ b/backend/recover-code-from-cursor-db.js @@ -229,6 +229,8 @@ function extractCodeBlocks(obj, blocks = []) { + + diff --git a/backend/restore_job_common.sql b/backend/restore_job_common.sql index 13cf99c5..be209c4a 100644 --- a/backend/restore_job_common.sql +++ b/backend/restore_job_common.sql @@ -29,3 +29,5 @@ CREATE TABLE IF NOT EXISTS platform_schema.job_common ( + + diff --git a/backend/restore_pgboss_functions.sql b/backend/restore_pgboss_functions.sql index b5bc40e2..ae831ce1 100644 --- a/backend/restore_pgboss_functions.sql +++ b/backend/restore_pgboss_functions.sql @@ -103,3 +103,5 @@ CREATE OR REPLACE FUNCTION platform_schema.delete_queue(queue_name text) RETURNS + + diff --git a/backend/scripts/check-dc-tables.mjs b/backend/scripts/check-dc-tables.mjs index ce0d97ec..d5919d3e 100644 --- a/backend/scripts/check-dc-tables.mjs +++ b/backend/scripts/check-dc-tables.mjs @@ -248,6 +248,8 @@ checkDCTables(); + + diff --git a/backend/scripts/create-capability-schema.sql b/backend/scripts/create-capability-schema.sql index 7379934b..2d780178 100644 --- a/backend/scripts/create-capability-schema.sql +++ b/backend/scripts/create-capability-schema.sql @@ -4,3 +4,5 @@ CREATE SCHEMA IF NOT EXISTS capability_schema; + + diff --git a/backend/scripts/create-tool-c-ai-history-table.mjs b/backend/scripts/create-tool-c-ai-history-table.mjs index 6459300f..80906dbf 100644 --- a/backend/scripts/create-tool-c-ai-history-table.mjs +++ b/backend/scripts/create-tool-c-ai-history-table.mjs @@ -200,6 +200,8 @@ createAiHistoryTable() + + diff --git a/backend/scripts/create-tool-c-table.js b/backend/scripts/create-tool-c-table.js index 31b157a8..f23ff632 100644 --- a/backend/scripts/create-tool-c-table.js +++ b/backend/scripts/create-tool-c-table.js @@ -187,6 +187,8 @@ createToolCTable() + + diff --git a/backend/scripts/create-tool-c-table.mjs b/backend/scripts/create-tool-c-table.mjs index 430111ee..161283ab 100644 --- a/backend/scripts/create-tool-c-table.mjs +++ b/backend/scripts/create-tool-c-table.mjs @@ -184,6 +184,8 @@ createToolCTable() + + diff --git a/backend/scripts/setup-prompt-system.ts b/backend/scripts/setup-prompt-system.ts index 4995f205..321193ba 100644 --- a/backend/scripts/setup-prompt-system.ts +++ b/backend/scripts/setup-prompt-system.ts @@ -114,3 +114,5 @@ main() + + diff --git a/backend/scripts/test-pkb-apis-simple.ts b/backend/scripts/test-pkb-apis-simple.ts index ecee54f9..265d2f34 100644 --- a/backend/scripts/test-pkb-apis-simple.ts +++ b/backend/scripts/test-pkb-apis-simple.ts @@ -334,3 +334,5 @@ runTests().catch(error => { + + diff --git a/backend/scripts/test-prompt-api.ts b/backend/scripts/test-prompt-api.ts index b2a46ac0..8715bc79 100644 --- a/backend/scripts/test-prompt-api.ts +++ b/backend/scripts/test-prompt-api.ts @@ -80,3 +80,5 @@ testAPI().catch(console.error); + + diff --git a/backend/scripts/verify-pkb-rvw-schema.ts b/backend/scripts/verify-pkb-rvw-schema.ts index 7e8635b3..19f8caa4 100644 --- a/backend/scripts/verify-pkb-rvw-schema.ts +++ b/backend/scripts/verify-pkb-rvw-schema.ts @@ -299,3 +299,5 @@ verifySchemas() + + diff --git a/backend/src/common/auth/jwt.service.ts b/backend/src/common/auth/jwt.service.ts index 6b9a3462..8f131f50 100644 --- a/backend/src/common/auth/jwt.service.ts +++ b/backend/src/common/auth/jwt.service.ts @@ -187,3 +187,5 @@ export const jwtService = new JWTService(); + + diff --git a/backend/src/common/jobs/utils.ts b/backend/src/common/jobs/utils.ts index d292e392..d0c3bfde 100644 --- a/backend/src/common/jobs/utils.ts +++ b/backend/src/common/jobs/utils.ts @@ -316,6 +316,8 @@ export function getBatchItems( + + diff --git a/backend/src/common/prompt/prompt.fallbacks.ts b/backend/src/common/prompt/prompt.fallbacks.ts index db859608..bdec66de 100644 --- a/backend/src/common/prompt/prompt.fallbacks.ts +++ b/backend/src/common/prompt/prompt.fallbacks.ts @@ -101,3 +101,5 @@ export function getAllFallbackCodes(): string[] { + + diff --git a/backend/src/common/prompt/prompt.routes.ts b/backend/src/common/prompt/prompt.routes.ts index f45cf4eb..e60f3043 100644 --- a/backend/src/common/prompt/prompt.routes.ts +++ b/backend/src/common/prompt/prompt.routes.ts @@ -19,6 +19,16 @@ import { import { authenticate, requirePermission } from '../auth/auth.middleware.js'; // Schema 定义 +const versionSchema = { + type: 'object', + nullable: true, + properties: { + version: { type: 'number' }, + status: { type: 'string' }, + createdAt: { type: 'string' }, + }, +}; + const listPromptsSchema = { querystring: { type: 'object', @@ -42,14 +52,9 @@ const listPromptsSchema = { module: { type: 'string' }, description: { type: 'string' }, variables: { type: 'array', items: { type: 'string' } }, - latestVersion: { - type: 'object', - properties: { - version: { type: 'number' }, - status: { type: 'string' }, - createdAt: { type: 'string' }, - }, - }, + activeVersion: versionSchema, // 🆕 生产版本 + draftVersion: versionSchema, // 🆕 草稿版本 + latestVersion: versionSchema, // 最新版本 updatedAt: { type: 'string' }, }, }, diff --git a/backend/src/common/prompt/prompt.service.ts b/backend/src/common/prompt/prompt.service.ts index 2c1ace93..6bd1aaca 100644 --- a/backend/src/common/prompt/prompt.service.ts +++ b/backend/src/common/prompt/prompt.service.ts @@ -60,22 +60,45 @@ export class PromptService { const { userId, skipCache = false } = options; try { + // 🔍 诊断日志:检查调试状态 + console.log(`[PromptService.get] 获取 Prompt: ${code}`); + console.log(` userId: ${userId || '(未提供)'}`); + console.log(` 当前调试用户数: ${this.debugStates.size}`); + + if (userId && this.debugStates.size > 0) { + const state = this.debugStates.get(userId); + if (state) { + console.log(` 用户调试状态: 模块=${Array.from(state.modules).join(',')}`); + } else { + console.log(` 用户调试状态: 未找到 (用户ID不在调试列表中)`); + console.log(` 调试列表中的用户: ${Array.from(this.debugStates.keys()).join(', ')}`); + } + } + // 1. 判断是否处于调试模式 const isDebugging = userId ? this.isDebugging(userId, code) : false; + console.log(` isDebugging: ${isDebugging}`); // 2. 获取 Prompt 版本 let version; if (isDebugging) { // 调试模式:优先获取 DRAFT + console.log(` → 调试模式,获取 DRAFT 版本`); version = await this.getDraftVersion(code); if (!version) { // 没有 DRAFT,降级到 ACTIVE + console.log(` → DRAFT 不存在,降级到 ACTIVE`); version = await this.getActiveVersion(code, skipCache); } } else { // 正常模式:获取 ACTIVE + console.log(` → 正常模式,获取 ACTIVE 版本`); version = await this.getActiveVersion(code, skipCache); } + + if (version) { + console.log(` → 返回版本: v${version.version} (${version.status})`); + } // 3. 如果数据库获取失败,使用兜底 if (!version) { @@ -248,16 +271,24 @@ export class PromptService { * @param enabled 是否开启 */ setDebugMode(userId: string, modules: string[], enabled: boolean): void { + console.log(`\n🔧 [PromptService.setDebugMode]`); + console.log(` userId: ${userId}`); + console.log(` modules: [${modules.join(', ')}]`); + console.log(` enabled: ${enabled}`); + if (enabled) { this.debugStates.set(userId, { userId, modules: new Set(modules), enabledAt: new Date(), }); - console.log(`[PromptService] Debug mode enabled for user ${userId}, modules: [${modules.join(', ')}]`); + console.log(` ✅ 调试模式已开启`); + console.log(` 当前调试用户数: ${this.debugStates.size}`); + console.log(` 所有调试用户: ${Array.from(this.debugStates.keys()).join(', ')}`); } else { this.debugStates.delete(userId); - console.log(`[PromptService] Debug mode disabled for user ${userId}`); + console.log(` ✅ 调试模式已关闭`); + console.log(` 当前调试用户数: ${this.debugStates.size}`); } } diff --git a/backend/src/common/prompt/prompt.types.ts b/backend/src/common/prompt/prompt.types.ts index 50c79b0d..5cd880c9 100644 --- a/backend/src/common/prompt/prompt.types.ts +++ b/backend/src/common/prompt/prompt.types.ts @@ -70,3 +70,5 @@ export interface VariableValidation { + + diff --git a/backend/src/legacy/controllers/chatController.ts b/backend/src/legacy/controllers/chatController.ts index a8305800..ef182b7d 100644 --- a/backend/src/legacy/controllers/chatController.ts +++ b/backend/src/legacy/controllers/chatController.ts @@ -85,8 +85,8 @@ export class ChatController { reply: FastifyReply ) { try { - // TODO: 从JWT token获取userId - const userId = 'user-mock-001'; + // 从JWT token获取userId,如果没有认证则使用默认用户 + const userId = request.user?.userId || 'user-mock-001'; const { content, modelType, knowledgeBaseIds, documentIds, fullTextDocumentIds, conversationId } = request.body; diff --git a/backend/src/legacy/routes/chatRoutes.ts b/backend/src/legacy/routes/chatRoutes.ts index 97710483..5819e4b6 100644 --- a/backend/src/legacy/routes/chatRoutes.ts +++ b/backend/src/legacy/routes/chatRoutes.ts @@ -1,15 +1,16 @@ import { FastifyInstance } from 'fastify'; import { chatController } from '../controllers/chatController.js'; +import { optionalAuthenticate } from '../../common/auth/auth.middleware.js'; export async function chatRoutes(fastify: FastifyInstance) { - // 发送消息(流式输出) - fastify.post('/chat/stream', chatController.sendMessageStream.bind(chatController)); + // 发送消息(流式输出)- 使用可选认证,优先使用真实用户ID + fastify.post('/chat/stream', { preHandler: [optionalAuthenticate] }, chatController.sendMessageStream.bind(chatController)); - // 获取对话列表 - fastify.get('/chat/conversations', chatController.getConversations.bind(chatController)); + // 获取对话列表 - 使用可选认证 + fastify.get('/chat/conversations', { preHandler: [optionalAuthenticate] }, chatController.getConversations.bind(chatController)); - // 删除对话 - fastify.delete('/chat/conversations/:id', chatController.deleteConversation.bind(chatController)); + // 删除对话 - 使用可选认证 + fastify.delete('/chat/conversations/:id', { preHandler: [optionalAuthenticate] }, chatController.deleteConversation.bind(chatController)); } diff --git a/backend/src/modules/admin/routes/tenantRoutes.ts b/backend/src/modules/admin/routes/tenantRoutes.ts index 5498b58f..d891d499 100644 --- a/backend/src/modules/admin/routes/tenantRoutes.ts +++ b/backend/src/modules/admin/routes/tenantRoutes.ts @@ -76,3 +76,5 @@ export async function moduleRoutes(fastify: FastifyInstance) { } + + diff --git a/backend/src/modules/admin/types/tenant.types.ts b/backend/src/modules/admin/types/tenant.types.ts index 517d5a08..b1856cb4 100644 --- a/backend/src/modules/admin/types/tenant.types.ts +++ b/backend/src/modules/admin/types/tenant.types.ts @@ -106,3 +106,5 @@ export interface PaginatedResponse { } + + diff --git a/backend/src/modules/asl/fulltext-screening/__tests__/api-integration-test.ts b/backend/src/modules/asl/fulltext-screening/__tests__/api-integration-test.ts index 3b19b01f..ba676aec 100644 --- a/backend/src/modules/asl/fulltext-screening/__tests__/api-integration-test.ts +++ b/backend/src/modules/asl/fulltext-screening/__tests__/api-integration-test.ts @@ -352,6 +352,8 @@ runTests().catch((error) => { + + diff --git a/backend/src/modules/asl/fulltext-screening/__tests__/e2e-real-test-v2.ts b/backend/src/modules/asl/fulltext-screening/__tests__/e2e-real-test-v2.ts index 8d356053..890f5c19 100644 --- a/backend/src/modules/asl/fulltext-screening/__tests__/e2e-real-test-v2.ts +++ b/backend/src/modules/asl/fulltext-screening/__tests__/e2e-real-test-v2.ts @@ -293,6 +293,8 @@ runTest() + + diff --git a/backend/src/modules/asl/fulltext-screening/__tests__/fulltext-screening-api.http b/backend/src/modules/asl/fulltext-screening/__tests__/fulltext-screening-api.http index d2e2f481..0d96327a 100644 --- a/backend/src/modules/asl/fulltext-screening/__tests__/fulltext-screening-api.http +++ b/backend/src/modules/asl/fulltext-screening/__tests__/fulltext-screening-api.http @@ -331,6 +331,8 @@ Content-Type: application/json + + diff --git a/backend/src/modules/dc/tool-b/services/ConflictDetectionService.ts b/backend/src/modules/dc/tool-b/services/ConflictDetectionService.ts index 643032fa..8d04450f 100644 --- a/backend/src/modules/dc/tool-b/services/ConflictDetectionService.ts +++ b/backend/src/modules/dc/tool-b/services/ConflictDetectionService.ts @@ -267,6 +267,8 @@ export const conflictDetectionService = new ConflictDetectionService(); + + diff --git a/backend/src/modules/dc/tool-c/README.md b/backend/src/modules/dc/tool-c/README.md index 530c584b..6f016a59 100644 --- a/backend/src/modules/dc/tool-c/README.md +++ b/backend/src/modules/dc/tool-c/README.md @@ -217,6 +217,8 @@ curl -X POST http://localhost:3000/api/v1/dc/tool-c/test/execute \ + + diff --git a/backend/src/modules/dc/tool-c/controllers/StreamAIController.ts b/backend/src/modules/dc/tool-c/controllers/StreamAIController.ts index 7108757b..a71f2090 100644 --- a/backend/src/modules/dc/tool-c/controllers/StreamAIController.ts +++ b/backend/src/modules/dc/tool-c/controllers/StreamAIController.ts @@ -271,6 +271,8 @@ export const streamAIController = new StreamAIController(); + + diff --git a/backend/src/modules/iit-manager/agents/SessionMemory.ts b/backend/src/modules/iit-manager/agents/SessionMemory.ts index fc41b8d5..27553de9 100644 --- a/backend/src/modules/iit-manager/agents/SessionMemory.ts +++ b/backend/src/modules/iit-manager/agents/SessionMemory.ts @@ -183,3 +183,5 @@ logger.info('[SessionMemory] 会话记忆管理器已启动', { + + diff --git a/backend/src/modules/iit-manager/check-iit-table-structure.ts b/backend/src/modules/iit-manager/check-iit-table-structure.ts index 88959889..9756b9c2 100644 --- a/backend/src/modules/iit-manager/check-iit-table-structure.ts +++ b/backend/src/modules/iit-manager/check-iit-table-structure.ts @@ -117,3 +117,5 @@ checkTableStructure(); + + diff --git a/backend/src/modules/iit-manager/check-project-config.ts b/backend/src/modules/iit-manager/check-project-config.ts index 2ad18bed..c84073a7 100644 --- a/backend/src/modules/iit-manager/check-project-config.ts +++ b/backend/src/modules/iit-manager/check-project-config.ts @@ -104,3 +104,5 @@ checkProjectConfig().catch(console.error); + + diff --git a/backend/src/modules/iit-manager/check-test-project-in-db.ts b/backend/src/modules/iit-manager/check-test-project-in-db.ts index 86523b99..e4893bee 100644 --- a/backend/src/modules/iit-manager/check-test-project-in-db.ts +++ b/backend/src/modules/iit-manager/check-test-project-in-db.ts @@ -86,3 +86,5 @@ main(); + + diff --git a/backend/src/modules/iit-manager/docs/微信服务号接入指南.md b/backend/src/modules/iit-manager/docs/微信服务号接入指南.md index e7fd566f..5c842d0f 100644 --- a/backend/src/modules/iit-manager/docs/微信服务号接入指南.md +++ b/backend/src/modules/iit-manager/docs/微信服务号接入指南.md @@ -543,3 +543,5 @@ URL: https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback + + diff --git a/backend/src/modules/iit-manager/generate-wechat-tokens.ts b/backend/src/modules/iit-manager/generate-wechat-tokens.ts index c6afa2a1..0927b64c 100644 --- a/backend/src/modules/iit-manager/generate-wechat-tokens.ts +++ b/backend/src/modules/iit-manager/generate-wechat-tokens.ts @@ -178,3 +178,5 @@ console.log(''); + + diff --git a/backend/src/modules/iit-manager/services/PatientWechatService.ts b/backend/src/modules/iit-manager/services/PatientWechatService.ts index 111a5137..e95a23ad 100644 --- a/backend/src/modules/iit-manager/services/PatientWechatService.ts +++ b/backend/src/modules/iit-manager/services/PatientWechatService.ts @@ -495,3 +495,5 @@ export const patientWechatService = new PatientWechatService(); + + diff --git a/backend/src/modules/iit-manager/test-chatservice-dify.ts b/backend/src/modules/iit-manager/test-chatservice-dify.ts index 32089739..e976b512 100644 --- a/backend/src/modules/iit-manager/test-chatservice-dify.ts +++ b/backend/src/modules/iit-manager/test-chatservice-dify.ts @@ -140,3 +140,5 @@ testDifyIntegration().catch(error => { + + diff --git a/backend/src/modules/iit-manager/test-iit-database.ts b/backend/src/modules/iit-manager/test-iit-database.ts index 826ebf21..2510b0f9 100644 --- a/backend/src/modules/iit-manager/test-iit-database.ts +++ b/backend/src/modules/iit-manager/test-iit-database.ts @@ -167,5 +167,7 @@ testIitDatabase() + + diff --git a/backend/src/modules/iit-manager/test-patient-wechat-config.ts b/backend/src/modules/iit-manager/test-patient-wechat-config.ts index 2fce0610..c479eb0c 100644 --- a/backend/src/modules/iit-manager/test-patient-wechat-config.ts +++ b/backend/src/modules/iit-manager/test-patient-wechat-config.ts @@ -155,3 +155,5 @@ if (hasError) { + + diff --git a/backend/src/modules/iit-manager/test-patient-wechat-url-verify.ts b/backend/src/modules/iit-manager/test-patient-wechat-url-verify.ts index f066fb23..b39fdba1 100644 --- a/backend/src/modules/iit-manager/test-patient-wechat-url-verify.ts +++ b/backend/src/modules/iit-manager/test-patient-wechat-url-verify.ts @@ -181,3 +181,5 @@ async function testUrlVerification() { + + diff --git a/backend/src/modules/iit-manager/test-redcap-query-from-db.ts b/backend/src/modules/iit-manager/test-redcap-query-from-db.ts index bfd61ea5..113d5478 100644 --- a/backend/src/modules/iit-manager/test-redcap-query-from-db.ts +++ b/backend/src/modules/iit-manager/test-redcap-query-from-db.ts @@ -262,3 +262,5 @@ main().catch((error) => { + + diff --git a/backend/src/modules/iit-manager/test-wechat-mp-local.ps1 b/backend/src/modules/iit-manager/test-wechat-mp-local.ps1 index 3b884410..de8cda36 100644 --- a/backend/src/modules/iit-manager/test-wechat-mp-local.ps1 +++ b/backend/src/modules/iit-manager/test-wechat-mp-local.ps1 @@ -146,3 +146,5 @@ Write-Host "" + + diff --git a/backend/src/modules/iit-manager/types/index.ts b/backend/src/modules/iit-manager/types/index.ts index 2709e771..5fe19fde 100644 --- a/backend/src/modules/iit-manager/types/index.ts +++ b/backend/src/modules/iit-manager/types/index.ts @@ -237,5 +237,7 @@ export interface CachedProtocolRules { + + diff --git a/backend/src/modules/pkb/controllers/chatController.ts b/backend/src/modules/pkb/controllers/chatController.ts new file mode 100644 index 00000000..e9ec9af1 --- /dev/null +++ b/backend/src/modules/pkb/controllers/chatController.ts @@ -0,0 +1,281 @@ +/** + * PKB模块 - Chat控制器 + * + * 知识库问答功能(全文阅读、逐篇精读模式) + * 强制要求用户认证 + * + * 简化版:不保存对话历史(PKB的全文阅读/逐篇精读是一次性问答) + */ + +import { FastifyRequest, FastifyReply } from 'fastify'; +import { ModelType } from '../../../common/llm/adapters/types.js'; +import { LLMFactory } from '../../../common/llm/adapters/LLMFactory.js'; +import { prisma } from '../../../config/database.js'; +import { logger } from '../../../common/logging/index.js'; + +/** + * 引用信息接口 + */ +interface Citation { + id: number; + fileName: string; + position: number; + score: number; + content: string; +} + +/** + * 提取文本片段(用于引用上下文) + */ +function extractContextPreview(text: string, maxLength: number = 100): string { + if (!text) return ''; + + const cleaned = text.replace(/\s+/g, ' ').trim(); + if (cleaned.length <= maxLength) { + return cleaned; + } + + const truncated = cleaned.substring(0, maxLength); + const lastPunctuation = Math.max( + truncated.lastIndexOf('。'), + truncated.lastIndexOf('!'), + truncated.lastIndexOf('?'), + truncated.lastIndexOf('.'), + truncated.lastIndexOf('!'), + truncated.lastIndexOf('?') + ); + + if (lastPunctuation > maxLength * 0.5) { + return truncated.substring(0, lastPunctuation + 1); + } + + return truncated + '...'; +} + +/** + * 格式化引用清单 + */ +function formatCitations(citations: Citation[]): string { + if (citations.length === 0) return ''; + + let result = '\n\n---\n\n📚 **参考文献**\n\n'; + + for (const cite of citations) { + const scorePercent = (cite.score * 100).toFixed(0); + const preview = extractContextPreview(cite.content, 100); + + result += `[${cite.id}] 📄 **${cite.fileName}** - 第${cite.position}段 (相关度${scorePercent}%)\n`; + result += ` "${preview}"\n\n`; + } + + return result; +} + +interface SendChatMessageBody { + content: string; + modelType: ModelType; + knowledgeBaseIds?: string[]; + documentIds?: string[]; + fullTextDocumentIds?: string[]; +} + +/** + * 发送消息(流式输出) + * + * POST /api/v2/pkb/chat/stream + */ +export async function sendMessageStream( + request: FastifyRequest<{ Body: SendChatMessageBody }>, + reply: FastifyReply +) { + try { + // 从认证中获取userId(已由authenticate中间件验证) + const userId = request.user!.userId; + + const { content, modelType, knowledgeBaseIds, fullTextDocumentIds } = request.body; + + logger.info('[PKB Chat] 收到对话请求', { + userId, + modelType, + knowledgeBaseIds: knowledgeBaseIds || [], + fullTextDocumentIds: fullTextDocumentIds || [], + }); + + // 验证modelType + const validModels = ['deepseek-v3', 'qwen3-72b', 'qwen-long', 'gemini-pro']; + if (!validModels.includes(modelType)) { + reply.code(400).send({ + success: false, + message: `不支持的模型类型: ${modelType}`, + }); + return; + } + + // 检索知识库上下文 + let knowledgeBaseContext = ''; + const allCitations: Citation[] = []; + + // 全文阅读模式 + if (fullTextDocumentIds && fullTextDocumentIds.length > 0) { + logger.info('[PKB Chat] 全文阅读模式', { documentCount: fullTextDocumentIds.length }); + + try { + const documents = await prisma.document.findMany({ + where: { + id: { in: fullTextDocumentIds }, + }, + select: { + id: true, + filename: true, + extractedText: true, + tokensCount: true, + }, + orderBy: { + filename: 'asc', + }, + }); + + const validDocuments = documents.filter(doc => doc.extractedText && doc.extractedText.trim().length > 0); + + if (validDocuments.length === 0) { + logger.warn('[PKB Chat] 所有文档都没有提取文本'); + } + + const fullTextParts: string[] = []; + + for (let i = 0; i < validDocuments.length; i++) { + const doc = validDocuments[i]; + const docNumber = i + 1; + + allCitations.push({ + id: docNumber, + fileName: doc.filename, + position: 0, + score: 1.0, + content: doc.extractedText?.substring(0, 200) || '(无内容)', + }); + + fullTextParts.push( + `【文献${docNumber}:${doc.filename}】\n\n${doc.extractedText}` + ); + } + + knowledgeBaseContext = fullTextParts.join('\n\n---\n\n'); + + const totalTokens = validDocuments.reduce((sum, doc) => sum + (doc.tokensCount || 0), 0); + + logger.info('[PKB Chat] 全文上下文已组装', { + totalDocuments: validDocuments.length, + totalCharacters: knowledgeBaseContext.length, + totalTokens, + }); + + // Token限制检查 + const QWEN_LONG_INPUT_LIMIT = 1000000; + const SYSTEM_OVERHEAD = 10000; + const SAFE_INPUT_LIMIT = QWEN_LONG_INPUT_LIMIT - SYSTEM_OVERHEAD; + + if (totalTokens > SAFE_INPUT_LIMIT) { + const errorMsg = `输入Token数量 (${totalTokens}) 超出限制 (${SAFE_INPUT_LIMIT})。请减少文献数量。`; + logger.error('[PKB Chat] Token超限', { totalTokens, limit: SAFE_INPUT_LIMIT }); + + reply.raw.writeHead(200, { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + }); + reply.raw.write(`data: ${JSON.stringify({ + content: `\n\n⚠️ **Token数量超限**\n\n${errorMsg}`, + role: 'assistant', + error: true, + })}\n\n`); + reply.raw.write('data: [DONE]\n\n'); + return reply.raw.end(); + } + + } catch (error) { + logger.error('[PKB Chat] 加载文献全文失败:', error); + } + } + + // 组装消息 + let systemPrompt = '你是一个专业、友好的AI助手。'; + + if (fullTextDocumentIds && fullTextDocumentIds.length > 0) { + systemPrompt = '你是一个专业的学术文献分析助手。用户会提供多篇文献的完整全文,每篇文献用【文献N:文件名】标记。请认真阅读所有文献,进行深入的综合分析。在回答时请引用具体文献,使用【文献N】格式。'; + } + + const messages: any[] = [ + { role: 'system', content: systemPrompt }, + ]; + + let userContent = content; + if (knowledgeBaseContext) { + if (fullTextDocumentIds && fullTextDocumentIds.length > 0) { + userContent = `${content}\n\n## 参考资料(文献全文)\n\n${knowledgeBaseContext}`; + } else { + userContent = `${content}\n\n## 参考资料\n\n${knowledgeBaseContext}`; + } + } + messages.push({ role: 'user', content: userContent }); + + // 设置SSE响应头 + reply.raw.writeHead(200, { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + 'Access-Control-Allow-Origin': '*', + }); + + // 流式输出 + const adapter = LLMFactory.getAdapter(modelType); + let fullContent = ''; + + const maxOutputTokens = fullTextDocumentIds && fullTextDocumentIds.length > 0 ? 6000 : 2000; + + logger.info('[PKB Chat] 开始LLM调用', { model: modelType, maxOutputTokens }); + + for await (const chunk of adapter.chatStream(messages, { + temperature: 0.7, + maxTokens: maxOutputTokens, + })) { + fullContent += chunk.content; + reply.raw.write(`data: ${JSON.stringify(chunk)}\n\n`); + } + + // 追加引用清单 + if (allCitations.length > 0) { + const citationsText = formatCitations(allCitations); + fullContent += citationsText; + reply.raw.write(`data: ${JSON.stringify({ content: citationsText, role: 'assistant' })}\n\n`); + } + + reply.raw.write('data: [DONE]\n\n'); + reply.raw.end(); + + logger.info('[PKB Chat] 对话完成', { + userId, + responseLength: fullContent.length, + citationsCount: allCitations.length, + }); + } catch (error: any) { + logger.error('[PKB Chat] 错误:', error); + + // 如果还没有发送响应头,返回JSON错误 + if (!reply.raw.headersSent) { + reply.code(500).send({ + success: false, + message: error.message || '服务器错误', + }); + } else { + // 已经发送了SSE头,尝试发送错误信息 + try { + reply.raw.write(`data: ${JSON.stringify({ error: true, message: error.message })}\n\n`); + reply.raw.write('data: [DONE]\n\n'); + reply.raw.end(); + } catch (e) { + // 忽略 + } + } + } +} diff --git a/backend/src/modules/pkb/routes/chatRoutes.ts b/backend/src/modules/pkb/routes/chatRoutes.ts new file mode 100644 index 00000000..beca2dfe --- /dev/null +++ b/backend/src/modules/pkb/routes/chatRoutes.ts @@ -0,0 +1,17 @@ +/** + * PKB模块 - Chat路由 + * + * 知识库问答功能(全文阅读、逐篇精读模式) + * 所有路由都需要认证 + */ + +import { FastifyInstance } from 'fastify'; +import { sendMessageStream } from '../controllers/chatController.js'; +import { authenticate, requireModule } from '../../../common/auth/auth.middleware.js'; + +export default async function chatRoutes(fastify: FastifyInstance) { + // 发送消息(流式输出) + fastify.post('/stream', { + preHandler: [authenticate, requireModule('PKB')] + }, sendMessageStream as any); +} diff --git a/backend/src/modules/pkb/routes/health.ts b/backend/src/modules/pkb/routes/health.ts index b136dc6c..554959ee 100644 --- a/backend/src/modules/pkb/routes/health.ts +++ b/backend/src/modules/pkb/routes/health.ts @@ -52,3 +52,5 @@ export default async function healthRoutes(fastify: FastifyInstance) { + + diff --git a/backend/src/modules/pkb/routes/index.ts b/backend/src/modules/pkb/routes/index.ts index 3c119eed..8256b137 100644 --- a/backend/src/modules/pkb/routes/index.ts +++ b/backend/src/modules/pkb/routes/index.ts @@ -4,6 +4,7 @@ import { FastifyInstance } from 'fastify'; import knowledgeBaseRoutes from './knowledgeBases.js'; import batchRoutes from './batchRoutes.js'; +import chatRoutes from './chatRoutes.js'; import healthRoutes from './health.js'; export default async function pkbRoutes(fastify: FastifyInstance) { @@ -15,5 +16,8 @@ export default async function pkbRoutes(fastify: FastifyInstance) { // 注册批处理路由 fastify.register(batchRoutes, { prefix: '/batch-tasks' }); + + // 注册Chat路由(全文阅读、逐篇精读) + fastify.register(chatRoutes, { prefix: '/chat' }); } diff --git a/backend/src/modules/pkb/services/documentService.ts b/backend/src/modules/pkb/services/documentService.ts index b3116800..14037969 100644 --- a/backend/src/modules/pkb/services/documentService.ts +++ b/backend/src/modules/pkb/services/documentService.ts @@ -39,6 +39,18 @@ export async function uploadDocument( throw new Error('Document limit exceeded. Maximum 50 documents per knowledge base'); } + // 3. 检查文档是否已存在(同名文件查重) + const existingDoc = await prisma.document.findFirst({ + where: { + kbId, + filename: filename, + }, + }); + + if (existingDoc) { + throw new Error(`文档 "${filename}" 已存在,请勿重复上传`); + } + // 3. 在数据库中创建文档记录(状态:uploading) const document = await prisma.document.create({ data: { diff --git a/backend/src/modules/rvw/__tests__/api.http b/backend/src/modules/rvw/__tests__/api.http index baaf05f9..2c509795 100644 --- a/backend/src/modules/rvw/__tests__/api.http +++ b/backend/src/modules/rvw/__tests__/api.http @@ -130,3 +130,5 @@ Content-Type: application/json + + diff --git a/backend/src/modules/rvw/__tests__/test-api.ps1 b/backend/src/modules/rvw/__tests__/test-api.ps1 index d06ecb8d..0f88fb1b 100644 --- a/backend/src/modules/rvw/__tests__/test-api.ps1 +++ b/backend/src/modules/rvw/__tests__/test-api.ps1 @@ -115,3 +115,5 @@ Write-Host " - 删除任务: DELETE $BaseUrl/api/v2/rvw/tasks/{taskId}" -Foregr + + diff --git a/backend/src/modules/rvw/index.ts b/backend/src/modules/rvw/index.ts index 2d4e48d8..c208c3a6 100644 --- a/backend/src/modules/rvw/index.ts +++ b/backend/src/modules/rvw/index.ts @@ -29,3 +29,5 @@ export * from './services/utils.js'; + + diff --git a/backend/src/modules/rvw/services/utils.ts b/backend/src/modules/rvw/services/utils.ts index 45eb9fb1..681795c8 100644 --- a/backend/src/modules/rvw/services/utils.ts +++ b/backend/src/modules/rvw/services/utils.ts @@ -120,3 +120,5 @@ export function validateAgentSelection(agents: string[]): void { + + diff --git a/backend/src/tests/README.md b/backend/src/tests/README.md index b269343f..d26bc561 100644 --- a/backend/src/tests/README.md +++ b/backend/src/tests/README.md @@ -417,6 +417,8 @@ SET session_replication_role = 'origin'; + + diff --git a/backend/src/tests/verify-test1-database.sql b/backend/src/tests/verify-test1-database.sql index 3f6827ae..386d7a42 100644 --- a/backend/src/tests/verify-test1-database.sql +++ b/backend/src/tests/verify-test1-database.sql @@ -119,6 +119,8 @@ WHERE key = 'verify_test'; + + diff --git a/backend/src/tests/verify-test1-database.ts b/backend/src/tests/verify-test1-database.ts index 0b9d3a32..14f3b94e 100644 --- a/backend/src/tests/verify-test1-database.ts +++ b/backend/src/tests/verify-test1-database.ts @@ -262,6 +262,8 @@ verifyDatabase() + + diff --git a/backend/src/types/global.d.ts b/backend/src/types/global.d.ts index a6f07d20..457e77f0 100644 --- a/backend/src/types/global.d.ts +++ b/backend/src/types/global.d.ts @@ -52,6 +52,8 @@ export {} + + diff --git a/backend/sync-dc-database.ps1 b/backend/sync-dc-database.ps1 index 4f17a48e..889349ac 100644 --- a/backend/sync-dc-database.ps1 +++ b/backend/sync-dc-database.ps1 @@ -75,6 +75,8 @@ Write-Host "✅ 完成!" -ForegroundColor Green + + diff --git a/backend/temp_check.sql b/backend/temp_check.sql index 601ce2ed..8feebae5 100644 --- a/backend/temp_check.sql +++ b/backend/temp_check.sql @@ -3,3 +3,5 @@ SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('p + + diff --git a/backend/test-pkb-migration.http b/backend/test-pkb-migration.http index bba261ae..9d300da4 100644 --- a/backend/test-pkb-migration.http +++ b/backend/test-pkb-migration.http @@ -166,3 +166,5 @@ DELETE {{baseUrl}}/api/v2/pkb/knowledge/knowledge-bases/{{testKbId}} + + diff --git a/backend/test-tool-c-advanced-scenarios.mjs b/backend/test-tool-c-advanced-scenarios.mjs index 5f22b4ea..9a27a25f 100644 --- a/backend/test-tool-c-advanced-scenarios.mjs +++ b/backend/test-tool-c-advanced-scenarios.mjs @@ -362,6 +362,8 @@ runAdvancedTests().catch(error => { + + diff --git a/backend/test-tool-c-day2.mjs b/backend/test-tool-c-day2.mjs index 1e22cb8e..f007820d 100644 --- a/backend/test-tool-c-day2.mjs +++ b/backend/test-tool-c-day2.mjs @@ -428,6 +428,8 @@ runAllTests() + + diff --git a/backend/test-tool-c-day3.mjs b/backend/test-tool-c-day3.mjs index 4f593e81..f97d5075 100644 --- a/backend/test-tool-c-day3.mjs +++ b/backend/test-tool-c-day3.mjs @@ -386,6 +386,8 @@ runAllTests() + + diff --git a/backend/verify_all_users.ts b/backend/verify_all_users.ts index fb56423d..ffcc21ce 100644 --- a/backend/verify_all_users.ts +++ b/backend/verify_all_users.ts @@ -23,3 +23,5 @@ main() + + diff --git a/backend/verify_functions.ts b/backend/verify_functions.ts index d0b74b5a..29c8e1e3 100644 --- a/backend/verify_functions.ts +++ b/backend/verify_functions.ts @@ -21,3 +21,5 @@ main() + + diff --git a/backend/verify_job_common.ts b/backend/verify_job_common.ts index 374cd4f5..7e95f335 100644 --- a/backend/verify_job_common.ts +++ b/backend/verify_job_common.ts @@ -33,3 +33,5 @@ main() + + diff --git a/backend/verify_mock_user.ts b/backend/verify_mock_user.ts index 6e7b616e..d81766e3 100644 --- a/backend/verify_mock_user.ts +++ b/backend/verify_mock_user.ts @@ -22,3 +22,5 @@ main() + + diff --git a/backend/verify_system.ts b/backend/verify_system.ts index 7c464285..8549b33c 100644 --- a/backend/verify_system.ts +++ b/backend/verify_system.ts @@ -162,3 +162,5 @@ main() + + diff --git a/deploy-to-sae.ps1 b/deploy-to-sae.ps1 index bc6984a7..4baa0846 100644 --- a/deploy-to-sae.ps1 +++ b/deploy-to-sae.ps1 @@ -170,6 +170,8 @@ Set-Location .. + + diff --git a/docs/02-通用能力层/Postgres-Only异步任务处理指南.md b/docs/02-通用能力层/Postgres-Only异步任务处理指南.md index e02e6554..5ca9ae55 100644 --- a/docs/02-通用能力层/Postgres-Only异步任务处理指南.md +++ b/docs/02-通用能力层/Postgres-Only异步任务处理指南.md @@ -612,6 +612,8 @@ async saveProcessedData(recordId, newData) { + + diff --git a/docs/02-通用能力层/通用能力层技术债务清单.md b/docs/02-通用能力层/通用能力层技术债务清单.md index eb3cf007..e44cc117 100644 --- a/docs/02-通用能力层/通用能力层技术债务清单.md +++ b/docs/02-通用能力层/通用能力层技术债务清单.md @@ -799,6 +799,8 @@ export const AsyncProgressBar: React.FC = ({ + + diff --git a/docs/03-业务模块/ADMIN-运营管理端/00-Phase3.5完成总结.md b/docs/03-业务模块/ADMIN-运营管理端/00-Phase3.5完成总结.md index c8faae4a..2ac8d864 100644 --- a/docs/03-业务模块/ADMIN-运营管理端/00-Phase3.5完成总结.md +++ b/docs/03-业务模块/ADMIN-运营管理端/00-Phase3.5完成总结.md @@ -295,3 +295,5 @@ Level 3: 兜底Prompt(缓存也失效) + + diff --git a/docs/03-业务模块/ADMIN-运营管理端/README.md b/docs/03-业务模块/ADMIN-运营管理端/README.md index 595b56f3..f087bd77 100644 --- a/docs/03-业务模块/ADMIN-运营管理端/README.md +++ b/docs/03-业务模块/ADMIN-运营管理端/README.md @@ -215,3 +215,5 @@ ADMIN-运营管理端/ + + diff --git a/docs/03-业务模块/ADMIN运营与INST机构管理端-文档体系建立完成.md b/docs/03-业务模块/ADMIN运营与INST机构管理端-文档体系建立完成.md index a15250be..adb9d66d 100644 --- a/docs/03-业务模块/ADMIN运营与INST机构管理端-文档体系建立完成.md +++ b/docs/03-业务模块/ADMIN运营与INST机构管理端-文档体系建立完成.md @@ -314,3 +314,5 @@ INST-机构管理端/ + + diff --git a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/01-AIA-V2.1开发计划.md b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/01-AIA-V2.1开发计划.md index ccbb5829..4182f5e7 100644 --- a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/01-AIA-V2.1开发计划.md +++ b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/01-AIA-V2.1开发计划.md @@ -538,3 +538,5 @@ frontend-v2/src/modules/aia/ + + diff --git a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/02-后端API设计.md b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/02-后端API设计.md index 680f6181..8cfb1284 100644 --- a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/02-后端API设计.md +++ b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/02-后端API设计.md @@ -566,3 +566,5 @@ Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + diff --git a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/03-前端组件设计.md b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/03-前端组件设计.md index 09c277a4..cd47b096 100644 --- a/docs/03-业务模块/AIA-AI智能问答/04-开发计划/03-前端组件设计.md +++ b/docs/03-业务模块/AIA-AI智能问答/04-开发计划/03-前端组件设计.md @@ -881,3 +881,5 @@ export interface SlashCommand { + + diff --git a/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md b/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md index 22fdf671..8f1760ea 100644 --- a/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md +++ b/docs/03-业务模块/ASL-AI智能文献/04-开发计划/05-全文复筛前端开发计划.md @@ -1292,6 +1292,8 @@ interface FulltextScreeningResult { + + diff --git a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端开发完成.md b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端开发完成.md index 05a305be..fd4e224e 100644 --- a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端开发完成.md +++ b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端开发完成.md @@ -406,6 +406,8 @@ GET /api/v1/asl/fulltext-screening/tasks/:taskId/export + + diff --git a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端逻辑调整.md b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端逻辑调整.md index c5065f41..4cf7220c 100644 --- a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端逻辑调整.md +++ b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-01-23_全文复筛前端逻辑调整.md @@ -349,6 +349,8 @@ Linter错误:0个 + + diff --git a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-23_Day5_全文复筛API开发.md b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-23_Day5_全文复筛API开发.md index 0d124a68..fea0acc3 100644 --- a/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-23_Day5_全文复筛API开发.md +++ b/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-23_Day5_全文复筛API开发.md @@ -508,6 +508,8 @@ Failed to open file '\\tmp\\extraction_service\\temp_10000_test.pdf' + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_AI_Few-shot示例库.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_AI_Few-shot示例库.md index fc1140df..54612d27 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_AI_Few-shot示例库.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_AI_Few-shot示例库.md @@ -574,6 +574,8 @@ df['creatinine'] = pd.to_numeric(df['creatinine'], errors='coerce') + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Bug修复总结_2025-12-08.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Bug修复总结_2025-12-08.md index fddb27ce..dee1f598 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Bug修复总结_2025-12-08.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Bug修复总结_2025-12-08.md @@ -412,6 +412,8 @@ npm run dev + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day3开发计划.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day3开发计划.md index c73be7a4..dcff81e3 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day3开发计划.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day3开发计划.md @@ -989,6 +989,8 @@ export const aiController = new AIController(); + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md index f39101fd..77e31aef 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md @@ -1323,6 +1323,8 @@ npm install react-markdown + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Pivot列顺序优化总结.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Pivot列顺序优化总结.md index 7ebf20f0..a42447ea 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Pivot列顺序优化总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Pivot列顺序优化总结.md @@ -231,6 +231,8 @@ FMA___基线 | FMA___1个月 | FMA___2个月 + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_方案B实施总结_2025-12-09.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_方案B实施总结_2025-12-09.md index 10c0fe88..92d60a48 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_方案B实施总结_2025-12-09.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_方案B实施总结_2025-12-09.md @@ -389,6 +389,8 @@ formula = "FMA总分(0-100) / 100" + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理_开发进度_2025-12-10.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理_开发进度_2025-12-10.md index 1f08e892..51b3209f 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理_开发进度_2025-12-10.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理_开发进度_2025-12-10.md @@ -223,6 +223,8 @@ async handleFillnaMice(request, reply) { + + diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理功能_更新说明.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理功能_更新说明.md index 10966832..8c74c125 100644 --- a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理功能_更新说明.md +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理功能_更新说明.md @@ -195,6 +195,8 @@ method: 'mean' | 'median' | 'mode' | 'constant' | 'ffill' | 'bfill' + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-02_工作总结.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-02_工作总结.md index 1a6941d2..4c6d0d4d 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-02_工作总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-02_工作总结.md @@ -345,6 +345,8 @@ Changes: + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day1开发完成总结.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day1开发完成总结.md index aa4669df..bae9efa7 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day1开发完成总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day1开发完成总结.md @@ -417,6 +417,8 @@ cd path; command + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md index 11cf0e19..ae12ab30 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md @@ -646,6 +646,8 @@ import { logger } from '../../../../common/logging/index.js'; + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_AI对话核心功能增强总结.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_AI对话核心功能增强总结.md index bcf90fa7..2e98e519 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_AI对话核心功能增强总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_AI对话核心功能增强总结.md @@ -650,6 +650,8 @@ Content-Length: 45234 + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Bug修复_DataGrid空数据防御.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Bug修复_DataGrid空数据防御.md index 5cbe734b..7013b889 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Bug修复_DataGrid空数据防御.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Bug修复_DataGrid空数据防御.md @@ -302,6 +302,8 @@ Response: + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5_Ant-Design-X重构完成.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5_Ant-Design-X重构完成.md index 8b9200cd..9fc7de0c 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5_Ant-Design-X重构完成.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5_Ant-Design-X重构完成.md @@ -455,6 +455,8 @@ Response: + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5最终总结.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5最终总结.md index f0818895..77749bed 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5最终总结.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_Day5最终总结.md @@ -449,6 +449,8 @@ import { ChatContainer } from '@/shared/components/Chat'; + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_UI优化与Bug修复.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_UI优化与Bug修复.md index afb48700..b703ad4e 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_UI优化与Bug修复.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_UI优化与Bug修复.md @@ -359,6 +359,8 @@ const initialMessages = defaultMessages.length > 0 ? defaultMessages : [{ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_后端API完整对接完成.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_后端API完整对接完成.md index d43823fd..980e7430 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_后端API完整对接完成.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_后端API完整对接完成.md @@ -399,6 +399,8 @@ python main.py + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_完整UI优化与功能增强.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_完整UI优化与功能增强.md index 914a4a28..712841fc 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_完整UI优化与功能增强.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_完整UI优化与功能增强.md @@ -647,6 +647,8 @@ http://localhost:5173/data-cleaning/tool-c + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_工具C_Day4前端基础完成.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_工具C_Day4前端基础完成.md index 922811ec..7707d1ed 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_工具C_Day4前端基础完成.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_工具C_Day4前端基础完成.md @@ -257,6 +257,8 @@ Day 5 (6-8小时): + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建完成总结-Day1.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建完成总结-Day1.md index 556645f0..64a1bd6a 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建完成总结-Day1.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建完成总结-Day1.md @@ -435,6 +435,8 @@ Docs: docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建 + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase1-Portal页面开发完成-2025-12-02.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase1-Portal页面开发完成-2025-12-02.md index 3c66d23c..a8bd3757 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase1-Portal页面开发完成-2025-12-02.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase1-Portal页面开发完成-2025-12-02.md @@ -410,6 +410,8 @@ const mockAssets: Asset[] = [ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase2-ToolB-Step1-2开发完成-2025-12-03.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase2-ToolB-Step1-2开发完成-2025-12-03.md index 89b44d42..cfc506ab 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase2-ToolB-Step1-2开发完成-2025-12-03.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Phase2-ToolB-Step1-2开发完成-2025-12-03.md @@ -394,6 +394,8 @@ frontend-v2/src/modules/dc/ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Portal页面UI优化-2025-12-02.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Portal页面UI优化-2025-12-02.md index 7aaf778f..92c8d203 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Portal页面UI优化-2025-12-02.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Portal页面UI优化-2025-12-02.md @@ -354,6 +354,8 @@ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Tool-B-MVP完成总结-2025-12-03.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Tool-B-MVP完成总结-2025-12-03.md index bcc004bf..dbd11a1c 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Tool-B-MVP完成总结-2025-12-03.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/Tool-B-MVP完成总结-2025-12-03.md @@ -308,6 +308,8 @@ ConflictDetectionService // 冲突检测(字段级对比) + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-2025-12-03.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-2025-12-03.md index 7f27c27f..03264f01 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-2025-12-03.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-2025-12-03.md @@ -357,6 +357,8 @@ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-Round2-2025-12-03.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-Round2-2025-12-03.md index b21ef3dd..fd9c2379 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-Round2-2025-12-03.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB-UI优化-Round2-2025-12-03.md @@ -320,6 +320,8 @@ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB浏览器测试计划-2025-12-03.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB浏览器测试计划-2025-12-03.md index 7892f0b0..4dc51293 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB浏览器测试计划-2025-12-03.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/ToolB浏览器测试计划-2025-12-03.md @@ -384,6 +384,8 @@ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/后端API测试报告-2025-12-02.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/后端API测试报告-2025-12-02.md index 063bd7f3..28393b0d 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/后端API测试报告-2025-12-02.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/后端API测试报告-2025-12-02.md @@ -472,6 +472,8 @@ Tool B后端代码**100%复用**了平台通用能力层,无任何重复开发 + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/待办事项-下一步工作.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/待办事项-下一步工作.md index 5a704807..cddb32f3 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/待办事项-下一步工作.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/待办事项-下一步工作.md @@ -318,6 +318,8 @@ + + diff --git a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/数据库验证报告-2025-12-02.md b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/数据库验证报告-2025-12-02.md index 94e329eb..2e8ae5c6 100644 --- a/docs/03-业务模块/DC-数据清洗整理/06-开发记录/数据库验证报告-2025-12-02.md +++ b/docs/03-业务模块/DC-数据清洗整理/06-开发记录/数据库验证报告-2025-12-02.md @@ -249,6 +249,8 @@ $ node scripts/check-dc-tables.mjs + + diff --git a/docs/03-业务模块/DC-数据清洗整理/07-技术债务/Tool-B技术债务清单.md b/docs/03-业务模块/DC-数据清洗整理/07-技术债务/Tool-B技术债务清单.md index 57ad3873..1a8a10a7 100644 --- a/docs/03-业务模块/DC-数据清洗整理/07-技术债务/Tool-B技术债务清单.md +++ b/docs/03-业务模块/DC-数据清洗整理/07-技术债务/Tool-B技术债务清单.md @@ -482,6 +482,8 @@ ${fields.map((f, i) => `${i + 1}. ${f.name}:${f.desc}`).join('\n')} + + diff --git a/docs/03-业务模块/IIT Manager Agent/02-技术设计/IIT Manager Agent 技术路径与架构设计.md b/docs/03-业务模块/IIT Manager Agent/02-技术设计/IIT Manager Agent 技术路径与架构设计.md index b18ead68..30f4009f 100644 --- a/docs/03-业务模块/IIT Manager Agent/02-技术设计/IIT Manager Agent 技术路径与架构设计.md +++ b/docs/03-业务模块/IIT Manager Agent/02-技术设计/IIT Manager Agent 技术路径与架构设计.md @@ -690,3 +690,5 @@ private async processMessageAsync(xmlData: any) { + + diff --git a/docs/03-业务模块/IIT Manager Agent/04-开发计划/REDCap对接技术方案与实施指南.md b/docs/03-业务模块/IIT Manager Agent/04-开发计划/REDCap对接技术方案与实施指南.md index 84a9af23..d90bb5ba 100644 --- a/docs/03-业务模块/IIT Manager Agent/04-开发计划/REDCap对接技术方案与实施指南.md +++ b/docs/03-业务模块/IIT Manager Agent/04-开发计划/REDCap对接技术方案与实施指南.md @@ -1084,3 +1084,5 @@ async function testIntegration() { + + diff --git a/docs/03-业务模块/IIT Manager Agent/04-开发计划/企业微信注册指南.md b/docs/03-业务模块/IIT Manager Agent/04-开发计划/企业微信注册指南.md index fc4a9514..a4448731 100644 --- a/docs/03-业务模块/IIT Manager Agent/04-开发计划/企业微信注册指南.md +++ b/docs/03-业务模块/IIT Manager Agent/04-开发计划/企业微信注册指南.md @@ -223,5 +223,7 @@ Content-Type: application/json + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-01-04-Dify知识库集成开发记录.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-01-04-Dify知识库集成开发记录.md index e4b0477e..0f5b6b6b 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-01-04-Dify知识库集成开发记录.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-01-04-Dify知识库集成开发记录.md @@ -645,3 +645,5 @@ REDCap API: exportRecords success { recordCount: 1 } + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day2-REDCap实时集成开发完成记录.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day2-REDCap实时集成开发完成记录.md index c87374d1..bf094da1 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day2-REDCap实时集成开发完成记录.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day2-REDCap实时集成开发完成记录.md @@ -651,3 +651,5 @@ backend/src/modules/iit-manager/ + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成与端到端测试完成记录.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成与端到端测试完成记录.md index 4a2bf262..584d452e 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成与端到端测试完成记录.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成与端到端测试完成记录.md @@ -801,3 +801,5 @@ CREATE TABLE iit_schema.wechat_tokens ( + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md index a1b18223..20ea2234 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md @@ -558,3 +558,5 @@ Day 3 的开发工作虽然遇到了多个技术问题,但最终成功完成 + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Phase1.5-AI对话集成REDCap完成记录.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Phase1.5-AI对话集成REDCap完成记录.md index e55e47d2..25a35eed 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/Phase1.5-AI对话集成REDCap完成记录.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/Phase1.5-AI对话集成REDCap完成记录.md @@ -325,3 +325,5 @@ AI: "出生日期:2017-01-04 + + diff --git a/docs/03-业务模块/IIT Manager Agent/06-开发记录/V1.1更新完成报告.md b/docs/03-业务模块/IIT Manager Agent/06-开发记录/V1.1更新完成报告.md index 2df393d4..173f842a 100644 --- a/docs/03-业务模块/IIT Manager Agent/06-开发记录/V1.1更新完成报告.md +++ b/docs/03-业务模块/IIT Manager Agent/06-开发记录/V1.1更新完成报告.md @@ -267,5 +267,7 @@ Day 4: REDCap EM(Webhook推送)← 作为增强,而非核心 + + diff --git a/docs/03-业务模块/IIT Manager Agent/07-技术债务/IIT Manager Agent 技术债务清单.md b/docs/03-业务模块/IIT Manager Agent/07-技术债务/IIT Manager Agent 技术债务清单.md index 91f2ce05..9edb1239 100644 --- a/docs/03-业务模块/IIT Manager Agent/07-技术债务/IIT Manager Agent 技术债务清单.md +++ b/docs/03-业务模块/IIT Manager Agent/07-技术债务/IIT Manager Agent 技术债务清单.md @@ -683,3 +683,5 @@ const answer = `根据研究方案[1]和CRF表格[2],纳入标准包括: + + diff --git a/docs/03-业务模块/INST-机构管理端/00-模块当前状态与开发指南.md b/docs/03-业务模块/INST-机构管理端/00-模块当前状态与开发指南.md index 2a49119f..cc146f84 100644 --- a/docs/03-业务模块/INST-机构管理端/00-模块当前状态与开发指南.md +++ b/docs/03-业务模块/INST-机构管理端/00-模块当前状态与开发指南.md @@ -440,3 +440,5 @@ export const calculateAvailableQuota = async (tenantId: string) => { + + diff --git a/docs/03-业务模块/INST-机构管理端/README.md b/docs/03-业务模块/INST-机构管理端/README.md index ad7f595d..212e5951 100644 --- a/docs/03-业务模块/INST-机构管理端/README.md +++ b/docs/03-业务模块/INST-机构管理端/README.md @@ -313,3 +313,5 @@ https://platform.example.com/t/pharma-abc/login + + diff --git a/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07-前端迁移与批处理功能完善.md b/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07-前端迁移与批处理功能完善.md index bd1c406e..64c844d3 100644 --- a/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07-前端迁移与批处理功能完善.md +++ b/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07-前端迁移与批处理功能完善.md @@ -363,3 +363,5 @@ const newResults = resultsData.map((docResult: any) => ({ + + diff --git a/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07_PKB模块前端V3设计实现.md b/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07_PKB模块前端V3设计实现.md index dacd8e21..fc77b46a 100644 --- a/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07_PKB模块前端V3设计实现.md +++ b/docs/03-业务模块/PKB-个人知识库/06-开发记录/2026-01-07_PKB模块前端V3设计实现.md @@ -236,3 +236,5 @@ const chatApi = axios.create({ + + diff --git a/docs/03-业务模块/Redcap/01-部署与配置/10-REDCap_Docker部署操作手册.md b/docs/03-业务模块/Redcap/01-部署与配置/10-REDCap_Docker部署操作手册.md index 0d1af142..43fdd055 100644 --- a/docs/03-业务模块/Redcap/01-部署与配置/10-REDCap_Docker部署操作手册.md +++ b/docs/03-业务模块/Redcap/01-部署与配置/10-REDCap_Docker部署操作手册.md @@ -773,3 +773,5 @@ docker exec redcap-apache php /tmp/create-redcap-password.php + + diff --git a/docs/03-业务模块/Redcap/README.md b/docs/03-业务模块/Redcap/README.md index 29e1560e..9d062f15 100644 --- a/docs/03-业务模块/Redcap/README.md +++ b/docs/03-业务模块/Redcap/README.md @@ -155,3 +155,5 @@ AIclinicalresearch/redcap-docker-dev/ + + diff --git a/docs/04-开发规范/09-数据库开发规范.md b/docs/04-开发规范/09-数据库开发规范.md index 0390b6ae..88d18b47 100644 --- a/docs/04-开发规范/09-数据库开发规范.md +++ b/docs/04-开发规范/09-数据库开发规范.md @@ -321,3 +321,5 @@ npx tsx check_iit_asl_data.ts + + diff --git a/docs/04-开发规范/10-模块认证规范.md b/docs/04-开发规范/10-模块认证规范.md index 37d9680a..9a766e5f 100644 --- a/docs/04-开发规范/10-模块认证规范.md +++ b/docs/04-开发规范/10-模块认证规范.md @@ -189,3 +189,5 @@ interface DecodedToken { + + diff --git a/docs/05-部署文档/02-SAE部署完全指南(产品经理版).md b/docs/05-部署文档/02-SAE部署完全指南(产品经理版).md index 77439928..2164f7c0 100644 --- a/docs/05-部署文档/02-SAE部署完全指南(产品经理版).md +++ b/docs/05-部署文档/02-SAE部署完全指南(产品经理版).md @@ -889,6 +889,8 @@ ACR镜像仓库: + + diff --git a/docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md b/docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md index 756c045b..7f2e2c16 100644 --- a/docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md +++ b/docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md @@ -1376,6 +1376,8 @@ SAE应用配置: + + diff --git a/docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md b/docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md index 3797d1e9..15c280ef 100644 --- a/docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md +++ b/docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md @@ -1192,6 +1192,8 @@ docker exec -e PGPASSWORD="密码" ai-clinical-postgres psql -h RDS地址 -U air + + diff --git a/docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md b/docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md index b31afcfd..97a87e9b 100644 --- a/docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md +++ b/docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md @@ -603,6 +603,8 @@ scripts/*.ts + + diff --git a/docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md b/docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md index 9a57bbfa..3f2ee118 100644 --- a/docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md +++ b/docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md @@ -291,6 +291,8 @@ Node.js后端部署成功后: + + diff --git a/docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md b/docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md index 2572eb20..b56642ae 100644 --- a/docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md +++ b/docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md @@ -514,6 +514,8 @@ Node.js后端 (SAE) ← http://172.17.173.88:3001 + + diff --git a/docs/05-部署文档/13-Node.js后端-镜像修复记录.md b/docs/05-部署文档/13-Node.js后端-镜像修复记录.md index 31e6af68..b3d3aaa5 100644 --- a/docs/05-部署文档/13-Node.js后端-镜像修复记录.md +++ b/docs/05-部署文档/13-Node.js后端-镜像修复记录.md @@ -229,6 +229,8 @@ curl http://localhost:3001/health + + diff --git a/docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md b/docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md index d55a14b7..8a688426 100644 --- a/docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md +++ b/docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md @@ -267,6 +267,8 @@ npm run dev + + diff --git a/docs/05-部署文档/16-前端Nginx-部署成功总结.md b/docs/05-部署文档/16-前端Nginx-部署成功总结.md index 2885004e..1f80b213 100644 --- a/docs/05-部署文档/16-前端Nginx-部署成功总结.md +++ b/docs/05-部署文档/16-前端Nginx-部署成功总结.md @@ -491,6 +491,8 @@ pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432 + + diff --git a/docs/05-部署文档/17-完整部署实战手册-2025版.md b/docs/05-部署文档/17-完整部署实战手册-2025版.md index 8dc14ea4..24ffd49a 100644 --- a/docs/05-部署文档/17-完整部署实战手册-2025版.md +++ b/docs/05-部署文档/17-完整部署实战手册-2025版.md @@ -1819,6 +1819,8 @@ curl http://8.140.53.236/ + + diff --git a/docs/05-部署文档/18-部署文档使用指南.md b/docs/05-部署文档/18-部署文档使用指南.md index de7b857f..746431f2 100644 --- a/docs/05-部署文档/18-部署文档使用指南.md +++ b/docs/05-部署文档/18-部署文档使用指南.md @@ -367,6 +367,8 @@ crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-se + + diff --git a/docs/05-部署文档/19-日常更新快速操作手册.md b/docs/05-部署文档/19-日常更新快速操作手册.md index 569062e8..5c073d53 100644 --- a/docs/05-部署文档/19-日常更新快速操作手册.md +++ b/docs/05-部署文档/19-日常更新快速操作手册.md @@ -689,6 +689,8 @@ docker login --username=gofeng117@163.com \ + + diff --git a/docs/05-部署文档/文档修正报告-20251214.md b/docs/05-部署文档/文档修正报告-20251214.md index 95821522..6bc5c60b 100644 --- a/docs/05-部署文档/文档修正报告-20251214.md +++ b/docs/05-部署文档/文档修正报告-20251214.md @@ -500,6 +500,8 @@ NAT网关成本¥100/月,对初创团队是一笔开销 + + diff --git a/docs/07-运维文档/03-SAE环境变量配置指南.md b/docs/07-运维文档/03-SAE环境变量配置指南.md index e48aedf8..be5678a1 100644 --- a/docs/07-运维文档/03-SAE环境变量配置指南.md +++ b/docs/07-运维文档/03-SAE环境变量配置指南.md @@ -405,6 +405,8 @@ curl http://你的SAE地址:3001/health + + diff --git a/docs/07-运维文档/05-Redis缓存与队列的区别说明.md b/docs/07-运维文档/05-Redis缓存与队列的区别说明.md index 8d0b04a7..912dbd4d 100644 --- a/docs/07-运维文档/05-Redis缓存与队列的区别说明.md +++ b/docs/07-运维文档/05-Redis缓存与队列的区别说明.md @@ -737,6 +737,8 @@ const job = await queue.getJob(jobId); + + diff --git a/docs/07-运维文档/06-长时间任务可靠性分析.md b/docs/07-运维文档/06-长时间任务可靠性分析.md index 6821e7b4..7dbd3529 100644 --- a/docs/07-运维文档/06-长时间任务可靠性分析.md +++ b/docs/07-运维文档/06-长时间任务可靠性分析.md @@ -504,6 +504,8 @@ processLiteraturesInBackground(task.id, projectId, testLiteratures); + + diff --git a/docs/07-运维文档/07-Redis使用需求分析(按模块).md b/docs/07-运维文档/07-Redis使用需求分析(按模块).md index 9ec25980..612621c8 100644 --- a/docs/07-运维文档/07-Redis使用需求分析(按模块).md +++ b/docs/07-运维文档/07-Redis使用需求分析(按模块).md @@ -981,6 +981,8 @@ ROI = (¥22,556 - ¥144) / ¥144 × 100% = 15,564% + + diff --git a/docs/08-项目管理/03-每周计划/2025-12-13-Postgres-Only架构改造完成.md b/docs/08-项目管理/03-每周计划/2025-12-13-Postgres-Only架构改造完成.md index 12035699..8640027c 100644 --- a/docs/08-项目管理/03-每周计划/2025-12-13-Postgres-Only架构改造完成.md +++ b/docs/08-项目管理/03-每周计划/2025-12-13-Postgres-Only架构改造完成.md @@ -1038,6 +1038,8 @@ Redis 实例:¥500/月 + + diff --git a/docs/08-项目管理/05-技术债务/通用对话服务抽取计划.md b/docs/08-项目管理/05-技术债务/通用对话服务抽取计划.md index bde392f7..cc30999d 100644 --- a/docs/08-项目管理/05-技术债务/通用对话服务抽取计划.md +++ b/docs/08-项目管理/05-技术债务/通用对话服务抽取计划.md @@ -496,6 +496,8 @@ import { ChatContainer } from '@/shared/components/Chat'; + + diff --git a/docs/08-项目管理/2026-01-11-数据库事故总结.md b/docs/08-项目管理/2026-01-11-数据库事故总结.md index 34514672..6d7ec7bc 100644 --- a/docs/08-项目管理/2026-01-11-数据库事故总结.md +++ b/docs/08-项目管理/2026-01-11-数据库事故总结.md @@ -205,3 +205,5 @@ VALUES ('user-mock-001', '13800000000', ..., 'tenant-mock-001', ...); + + diff --git a/docs/08-项目管理/PKB前端问题修复报告.md b/docs/08-项目管理/PKB前端问题修复报告.md index 2db83b5c..c812ff65 100644 --- a/docs/08-项目管理/PKB前端问题修复报告.md +++ b/docs/08-项目管理/PKB前端问题修复报告.md @@ -417,3 +417,5 @@ frontend-v2/src/modules/pkb/ + + diff --git a/docs/08-项目管理/PKB前端验证指南.md b/docs/08-项目管理/PKB前端验证指南.md index ea27627f..0455467e 100644 --- a/docs/08-项目管理/PKB前端验证指南.md +++ b/docs/08-项目管理/PKB前端验证指南.md @@ -279,3 +279,5 @@ npm run dev + + diff --git a/docs/08-项目管理/PKB功能审查报告-阶段0.md b/docs/08-项目管理/PKB功能审查报告-阶段0.md index 09ea821d..9245c0fa 100644 --- a/docs/08-项目管理/PKB功能审查报告-阶段0.md +++ b/docs/08-项目管理/PKB功能审查报告-阶段0.md @@ -794,3 +794,5 @@ AIA智能问答模块 + + diff --git a/docs/08-项目管理/PKB和RVW功能迁移计划.md b/docs/08-项目管理/PKB和RVW功能迁移计划.md index 9bdce0a0..49f72201 100644 --- a/docs/08-项目管理/PKB和RVW功能迁移计划.md +++ b/docs/08-项目管理/PKB和RVW功能迁移计划.md @@ -936,6 +936,8 @@ CREATE INDEX idx_rvw_tasks_created_at ON rvw_schema.review_tasks(created_at); + + diff --git a/docs/08-项目管理/PKB精细化优化报告.md b/docs/08-项目管理/PKB精细化优化报告.md index 9f48c53f..dca46414 100644 --- a/docs/08-项目管理/PKB精细化优化报告.md +++ b/docs/08-项目管理/PKB精细化优化报告.md @@ -592,3 +592,5 @@ const typography = { + + diff --git a/docs/08-项目管理/PKB迁移-超级安全执行计划.md b/docs/08-项目管理/PKB迁移-超级安全执行计划.md index f889aab6..cb7e4562 100644 --- a/docs/08-项目管理/PKB迁移-超级安全执行计划.md +++ b/docs/08-项目管理/PKB迁移-超级安全执行计划.md @@ -904,3 +904,5 @@ app.use('/api/v1/knowledge', (req, res) => { + + diff --git a/docs/08-项目管理/PKB迁移-阶段1完成报告.md b/docs/08-项目管理/PKB迁移-阶段1完成报告.md index 1b807c8e..54785830 100644 --- a/docs/08-项目管理/PKB迁移-阶段1完成报告.md +++ b/docs/08-项目管理/PKB迁移-阶段1完成报告.md @@ -218,3 +218,5 @@ rm -rf src/modules/pkb + + diff --git a/docs/08-项目管理/PKB迁移-阶段2完成报告.md b/docs/08-项目管理/PKB迁移-阶段2完成报告.md index f8009fe3..fb4c8ed0 100644 --- a/docs/08-项目管理/PKB迁移-阶段2完成报告.md +++ b/docs/08-项目管理/PKB迁移-阶段2完成报告.md @@ -393,3 +393,5 @@ GET /api/v2/pkb/batch-tasks/batch/templates + + diff --git a/docs/08-项目管理/PKB迁移-阶段2进行中.md b/docs/08-项目管理/PKB迁移-阶段2进行中.md index 19c70521..0062b112 100644 --- a/docs/08-项目管理/PKB迁移-阶段2进行中.md +++ b/docs/08-项目管理/PKB迁移-阶段2进行中.md @@ -37,3 +37,5 @@ import pkbRoutes from './modules/pkb/routes/index.js'; + + diff --git a/docs/08-项目管理/PKB迁移-阶段3完成报告.md b/docs/08-项目管理/PKB迁移-阶段3完成报告.md index 1786f0ac..4285edb0 100644 --- a/docs/08-项目管理/PKB迁移-阶段3完成报告.md +++ b/docs/08-项目管理/PKB迁移-阶段3完成报告.md @@ -306,3 +306,5 @@ backend/ + + diff --git a/docs/08-项目管理/PKB迁移-阶段4完成报告.md b/docs/08-项目管理/PKB迁移-阶段4完成报告.md index 74ee6c18..60b36150 100644 --- a/docs/08-项目管理/PKB迁移-阶段4完成报告.md +++ b/docs/08-项目管理/PKB迁移-阶段4完成报告.md @@ -517,3 +517,5 @@ const response = await fetch('/api/v2/pkb/batch-tasks/batch/execute', { + + diff --git a/extraction_service/.dockerignore b/extraction_service/.dockerignore index 81127fb2..7716dcb8 100644 --- a/extraction_service/.dockerignore +++ b/extraction_service/.dockerignore @@ -71,6 +71,8 @@ models/ + + diff --git a/extraction_service/operations/__init__.py b/extraction_service/operations/__init__.py index 0920da11..367911d5 100644 --- a/extraction_service/operations/__init__.py +++ b/extraction_service/operations/__init__.py @@ -59,6 +59,8 @@ __version__ = '1.0.0' + + diff --git a/extraction_service/operations/dropna.py b/extraction_service/operations/dropna.py index 2efae6d9..0955886b 100644 --- a/extraction_service/operations/dropna.py +++ b/extraction_service/operations/dropna.py @@ -192,6 +192,8 @@ def get_missing_summary(df: pd.DataFrame) -> dict: + + diff --git a/extraction_service/operations/filter.py b/extraction_service/operations/filter.py index 540d1428..7d76a7cf 100644 --- a/extraction_service/operations/filter.py +++ b/extraction_service/operations/filter.py @@ -152,6 +152,8 @@ def apply_filter( + + diff --git a/extraction_service/operations/unpivot.py b/extraction_service/operations/unpivot.py index 72b25b7d..a1f733d1 100644 --- a/extraction_service/operations/unpivot.py +++ b/extraction_service/operations/unpivot.py @@ -316,6 +316,8 @@ def get_unpivot_preview( + + diff --git a/extraction_service/test_dc_api.py b/extraction_service/test_dc_api.py index af1c2ec7..d03e0944 100644 --- a/extraction_service/test_dc_api.py +++ b/extraction_service/test_dc_api.py @@ -326,6 +326,8 @@ if __name__ == "__main__": + + diff --git a/extraction_service/test_execute_simple.py b/extraction_service/test_execute_simple.py index 5b4db083..a27640c7 100644 --- a/extraction_service/test_execute_simple.py +++ b/extraction_service/test_execute_simple.py @@ -92,6 +92,8 @@ except Exception as e: + + diff --git a/extraction_service/test_module.py b/extraction_service/test_module.py index 2f23cc25..bff29d62 100644 --- a/extraction_service/test_module.py +++ b/extraction_service/test_module.py @@ -72,6 +72,8 @@ except Exception as e: + + diff --git a/frontend-v2/.dockerignore b/frontend-v2/.dockerignore index 93400a8d..8f4c4386 100644 --- a/frontend-v2/.dockerignore +++ b/frontend-v2/.dockerignore @@ -91,6 +91,8 @@ vite.config.*.timestamp-* + + diff --git a/frontend-v2/docker-entrypoint.sh b/frontend-v2/docker-entrypoint.sh index 1fa61542..37d64c28 100644 --- a/frontend-v2/docker-entrypoint.sh +++ b/frontend-v2/docker-entrypoint.sh @@ -58,6 +58,8 @@ exec nginx -g 'daemon off;' + + diff --git a/frontend-v2/nginx.conf b/frontend-v2/nginx.conf index 8b288c32..15e54bfe 100644 --- a/frontend-v2/nginx.conf +++ b/frontend-v2/nginx.conf @@ -214,6 +214,8 @@ http { + + diff --git a/frontend-v2/src/common/api/axios.ts b/frontend-v2/src/common/api/axios.ts index 97decff0..88153327 100644 --- a/frontend-v2/src/common/api/axios.ts +++ b/frontend-v2/src/common/api/axios.ts @@ -44,3 +44,5 @@ export default apiClient; + + diff --git a/frontend-v2/src/framework/auth/AuthContext.tsx b/frontend-v2/src/framework/auth/AuthContext.tsx index 5ca56e06..f6893e43 100644 --- a/frontend-v2/src/framework/auth/AuthContext.tsx +++ b/frontend-v2/src/framework/auth/AuthContext.tsx @@ -207,3 +207,5 @@ export { AuthContext }; + + diff --git a/frontend-v2/src/framework/auth/api.ts b/frontend-v2/src/framework/auth/api.ts index e2ff1784..c42fc9c3 100644 --- a/frontend-v2/src/framework/auth/api.ts +++ b/frontend-v2/src/framework/auth/api.ts @@ -243,3 +243,5 @@ export async function logout(): Promise { + + diff --git a/frontend-v2/src/framework/auth/index.ts b/frontend-v2/src/framework/auth/index.ts index f5d81be2..dd80ee96 100644 --- a/frontend-v2/src/framework/auth/index.ts +++ b/frontend-v2/src/framework/auth/index.ts @@ -9,3 +9,5 @@ export * from './api'; + + diff --git a/frontend-v2/src/framework/auth/moduleApi.ts b/frontend-v2/src/framework/auth/moduleApi.ts index c3835b59..e206136f 100644 --- a/frontend-v2/src/framework/auth/moduleApi.ts +++ b/frontend-v2/src/framework/auth/moduleApi.ts @@ -33,3 +33,5 @@ export async function fetchUserModules(): Promise { } + + diff --git a/frontend-v2/src/framework/auth/types.ts b/frontend-v2/src/framework/auth/types.ts index 7b1cf5a1..7e955979 100644 --- a/frontend-v2/src/framework/auth/types.ts +++ b/frontend-v2/src/framework/auth/types.ts @@ -102,3 +102,5 @@ export interface AuthContextType extends AuthState { + + diff --git a/frontend-v2/src/modules/asl/components/FulltextDetailDrawer.tsx b/frontend-v2/src/modules/asl/components/FulltextDetailDrawer.tsx index ec451623..321ea1ea 100644 --- a/frontend-v2/src/modules/asl/components/FulltextDetailDrawer.tsx +++ b/frontend-v2/src/modules/asl/components/FulltextDetailDrawer.tsx @@ -561,6 +561,8 @@ export default FulltextDetailDrawer; + + diff --git a/frontend-v2/src/modules/dc/hooks/useAssets.ts b/frontend-v2/src/modules/dc/hooks/useAssets.ts index edd5c23e..888dade1 100644 --- a/frontend-v2/src/modules/dc/hooks/useAssets.ts +++ b/frontend-v2/src/modules/dc/hooks/useAssets.ts @@ -154,6 +154,8 @@ export const useAssets = (activeTab: AssetTabType) => { + + diff --git a/frontend-v2/src/modules/dc/hooks/useRecentTasks.ts b/frontend-v2/src/modules/dc/hooks/useRecentTasks.ts index 8ad9e0de..1eec8d44 100644 --- a/frontend-v2/src/modules/dc/hooks/useRecentTasks.ts +++ b/frontend-v2/src/modules/dc/hooks/useRecentTasks.ts @@ -144,6 +144,8 @@ export const useRecentTasks = () => { + + diff --git a/frontend-v2/src/modules/dc/pages/tool-c/components/DropnaDialog.tsx b/frontend-v2/src/modules/dc/pages/tool-c/components/DropnaDialog.tsx index 1596a17e..9fc64015 100644 --- a/frontend-v2/src/modules/dc/pages/tool-c/components/DropnaDialog.tsx +++ b/frontend-v2/src/modules/dc/pages/tool-c/components/DropnaDialog.tsx @@ -343,6 +343,8 @@ export default DropnaDialog; + + diff --git a/frontend-v2/src/modules/dc/pages/tool-c/components/MetricTimePanel.tsx b/frontend-v2/src/modules/dc/pages/tool-c/components/MetricTimePanel.tsx index 29fda690..4e00e2c3 100644 --- a/frontend-v2/src/modules/dc/pages/tool-c/components/MetricTimePanel.tsx +++ b/frontend-v2/src/modules/dc/pages/tool-c/components/MetricTimePanel.tsx @@ -428,6 +428,8 @@ export default MetricTimePanel; + + diff --git a/frontend-v2/src/modules/dc/pages/tool-c/components/PivotPanel.tsx b/frontend-v2/src/modules/dc/pages/tool-c/components/PivotPanel.tsx index 25135ff1..6476bbf4 100644 --- a/frontend-v2/src/modules/dc/pages/tool-c/components/PivotPanel.tsx +++ b/frontend-v2/src/modules/dc/pages/tool-c/components/PivotPanel.tsx @@ -314,6 +314,8 @@ export default PivotPanel; + + diff --git a/frontend-v2/src/modules/dc/pages/tool-c/hooks/useSessionStatus.ts b/frontend-v2/src/modules/dc/pages/tool-c/hooks/useSessionStatus.ts index d0eb5fc5..ddcc0664 100644 --- a/frontend-v2/src/modules/dc/pages/tool-c/hooks/useSessionStatus.ts +++ b/frontend-v2/src/modules/dc/pages/tool-c/hooks/useSessionStatus.ts @@ -114,6 +114,8 @@ export function useSessionStatus({ + + diff --git a/frontend-v2/src/modules/dc/pages/tool-c/types/index.ts b/frontend-v2/src/modules/dc/pages/tool-c/types/index.ts index 05f8c161..cf533641 100644 --- a/frontend-v2/src/modules/dc/pages/tool-c/types/index.ts +++ b/frontend-v2/src/modules/dc/pages/tool-c/types/index.ts @@ -106,6 +106,8 @@ export interface DataStats { + + diff --git a/frontend-v2/src/modules/dc/types/portal.ts b/frontend-v2/src/modules/dc/types/portal.ts index d20e634d..28bcfa49 100644 --- a/frontend-v2/src/modules/dc/types/portal.ts +++ b/frontend-v2/src/modules/dc/types/portal.ts @@ -102,6 +102,8 @@ export type AssetTabType = 'all' | 'processed' | 'raw'; + + diff --git a/frontend-v2/src/modules/pkb/api/knowledgeBaseApi.ts b/frontend-v2/src/modules/pkb/api/knowledgeBaseApi.ts index 7c6ff332..351eb397 100644 --- a/frontend-v2/src/modules/pkb/api/knowledgeBaseApi.ts +++ b/frontend-v2/src/modules/pkb/api/knowledgeBaseApi.ts @@ -176,6 +176,7 @@ export const documentApi = { headers: { 'Content-Type': 'multipart/form-data', }, + timeout: 120000, // 上传超时设为2分钟 onUploadProgress: (progressEvent) => { if (progressEvent.total && onProgress) { const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); @@ -183,7 +184,19 @@ export const documentApi = { } }, }); - return response.data.data; + + // 🔑 改进响应处理 + if (response.data?.success && response.data?.data) { + return response.data.data; + } + + // 兼容直接返回数据的情况 + if (response.data?.id) { + return response.data; + } + + console.warn('[documentApi.upload] 响应格式异常:', response.data); + throw new Error('上传响应格式异常'); }, /** diff --git a/frontend-v2/src/modules/pkb/components/DocumentUpload.tsx b/frontend-v2/src/modules/pkb/components/DocumentUpload.tsx index e51a1817..f89ec73f 100644 --- a/frontend-v2/src/modules/pkb/components/DocumentUpload.tsx +++ b/frontend-v2/src/modules/pkb/components/DocumentUpload.tsx @@ -1,6 +1,6 @@ -import React, { useState } from 'react'; -import { Upload, message, Progress, Card } from 'antd'; -import { InboxOutlined } from '@ant-design/icons'; +import React, { useState, useRef } from 'react'; +import { Upload, message, Progress, Card, Button } from 'antd'; +import { InboxOutlined, FileTextOutlined, CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined, DeleteOutlined, ClockCircleOutlined } from '@ant-design/icons'; import type { UploadProps } from 'antd'; import { useKnowledgeBaseStore } from '../stores/useKnowledgeBaseStore'; @@ -12,6 +12,18 @@ interface DocumentUploadProps { disabled?: boolean; maxDocuments?: number; currentDocumentCount?: number; + existingDocuments?: string[]; // 已存在的文档文件名列表 +} + +// 上传文件状态 +interface UploadFileStatus { + uid: string; + name: string; + size: number; + file: File; + status: 'waiting' | 'uploading' | 'success' | 'error'; + progress: number; + errorMessage?: string; } const DocumentUpload: React.FC = ({ @@ -20,9 +32,18 @@ const DocumentUpload: React.FC = ({ disabled = false, maxDocuments = 50, currentDocumentCount = 0, + existingDocuments = [], }) => { - const [uploading, setUploading] = useState(false); - const [uploadProgress, setUploadProgress] = useState(0); + const [uploadQueue, setUploadQueue] = useState([]); + const [isProcessing, setIsProcessing] = useState(false); + const processingRef = useRef(false); // 防止重复触发 + + // 获取当前知识库的文档列表用于查重 + const { documents } = useKnowledgeBaseStore(); + const existingFilenames = new Set([ + ...existingDocuments, + ...documents.map(d => d.filename.toLowerCase()) + ]); const allowedTypes = [ 'application/pdf', @@ -33,107 +54,343 @@ const DocumentUpload: React.FC = ({ ]; const allowedExtensions = ['.pdf', '.doc', '.docx', '.txt', '.md']; + const remainingSlots = maxDocuments - currentDocumentCount; + const isAtLimit = remainingSlots <= 0; - const isAtLimit = currentDocumentCount >= maxDocuments; - - const beforeUpload = (file: File) => { - // 检查文档数量限制 - if (isAtLimit) { - message.error(`已达到文档数量上限(${maxDocuments}个)`); - return Upload.LIST_IGNORE; - } - + // 验证单个文件 + const validateFile = (file: File, queueNames: Set): string | null => { // 检查文件类型 - if (!allowedTypes.includes(file.type) && !allowedExtensions.some(ext => file.name.endsWith(ext))) { - message.error(`不支持的文件类型。支持:PDF、DOC、DOCX、TXT、MD`); - return Upload.LIST_IGNORE; + if (!allowedTypes.includes(file.type) && !allowedExtensions.some(ext => file.name.toLowerCase().endsWith(ext))) { + return `不支持的文件类型`; } - - // 检查文件大小 (10MB) + + // 检查文件大小 const maxSize = 10 * 1024 * 1024; if (file.size > maxSize) { - message.error('文件大小不能超过 10MB'); - return Upload.LIST_IGNORE; + return `文件大小超过10MB`; } - // 不返回任何值,让 customRequest 处理上传 - }; + // 检查是否与已上传的文档重名 + if (existingFilenames.has(file.name.toLowerCase())) { + return `文档已存在,请勿重复上传`; + } - const customRequest: UploadProps['customRequest'] = async (options) => { - const { file, onSuccess, onError } = options; + // 检查是否与队列中的文件重名 + if (queueNames.has(file.name.toLowerCase())) { + return `队列中已有同名文件`; + } - try { - setUploading(true); - setUploadProgress(0); + return null; + }; - // 使用 knowledgeBaseStore 的 uploadDocument 方法 - await useKnowledgeBaseStore.getState().uploadDocument( - kbId, - file as File, - (progress) => { - setUploadProgress(progress); - } - ); + // 格式化文件大小 + const formatFileSize = (bytes: number): string => { + if (bytes < 1024) return bytes + ' B'; + if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; + return (bytes / 1024 / 1024).toFixed(1) + ' MB'; + }; - message.success(`${(file as File).name} 上传成功`); + // 批量上传前的文件处理 + const beforeUpload: UploadProps['beforeUpload'] = (file, fileList) => { + // 只在第一个文件时处理整个列表,避免重复 + if (fileList.indexOf(file) !== 0) { + return false; + } + + // 计算可添加的文件数 + const currentQueueCount = uploadQueue.filter(f => f.status === 'waiting' || f.status === 'uploading').length; + const availableSlots = remainingSlots - currentQueueCount; + + if (availableSlots <= 0) { + message.error(`已达到文档数量上限,无法添加更多文件`); + return false; + } + + // 收集队列中已有的文件名 + const queueNames = new Set(uploadQueue.map(q => q.name.toLowerCase())); + + // 验证并添加文件 + const newFiles: UploadFileStatus[] = []; + const errors: string[] = []; + let skippedCount = 0; + + for (let i = 0; i < Math.min(fileList.length, availableSlots); i++) { + const f = fileList[i]; + const error = validateFile(f, queueNames); - if (onSuccess) { - onSuccess('ok'); + if (error) { + errors.push(`${f.name}: ${error}`); + skippedCount++; + continue; } - // 通知父组件刷新文档列表 - onUploadSuccess(); - } catch (error: any) { - console.error('Upload error:', error); - message.error(error.message || '上传失败'); - - if (onError) { - onError(error); + // 添加到临时集合,防止同批次中的重复文件 + queueNames.add(f.name.toLowerCase()); + + newFiles.push({ + uid: `upload-${Date.now()}-${i}-${Math.random().toString(36).substr(2, 9)}`, + name: f.name, + size: f.size, + file: f, + status: 'waiting', + progress: 0, + }); + } + + // 超出配额的文件 + if (fileList.length > availableSlots) { + skippedCount += fileList.length - availableSlots; + } + + // 显示错误提示 + if (errors.length > 0) { + errors.forEach(err => message.warning(err)); + } + if (fileList.length > availableSlots) { + message.warning(`已达到上传配额限制,${fileList.length - availableSlots} 个文件被跳过`); + } + + // 添加有效文件到队列 + if (newFiles.length > 0) { + setUploadQueue(prev => [...prev, ...newFiles]); + message.info(`已添加 ${newFiles.length} 个文件到上传队列`); + } + + return false; // 阻止默认上传 + }; + + // 开始上传 + const startUpload = async () => { + if (processingRef.current) return; + + const waitingFiles = uploadQueue.filter(f => f.status === 'waiting'); + if (waitingFiles.length === 0) { + message.info('没有待上传的文件'); + return; + } + + processingRef.current = true; + setIsProcessing(true); + + let successCount = 0; + let failCount = 0; + + for (const queueItem of waitingFiles) { + // 更新状态为上传中 + setUploadQueue(prev => prev.map(item => + item.uid === queueItem.uid ? { ...item, status: 'uploading' as const, progress: 0 } : item + )); + + try { + await useKnowledgeBaseStore.getState().uploadDocument( + kbId, + queueItem.file, + (progress) => { + setUploadQueue(prev => prev.map(item => + item.uid === queueItem.uid ? { ...item, progress } : item + )); + } + ); + + // 上传成功 + setUploadQueue(prev => prev.map(item => + item.uid === queueItem.uid ? { ...item, status: 'success' as const, progress: 100 } : item + )); + successCount++; + onUploadSuccess(); + + } catch (error: any) { + // 上传失败 + setUploadQueue(prev => prev.map(item => + item.uid === queueItem.uid ? { + ...item, + status: 'error' as const, + errorMessage: error.message || '上传失败' + } : item + )); + failCount++; } - } finally { - setUploading(false); - setUploadProgress(0); + } + + processingRef.current = false; + setIsProcessing(false); + + // 显示汇总结果 + if (successCount > 0 && failCount === 0) { + message.success(`全部 ${successCount} 个文件上传成功!`); + } else if (successCount > 0 && failCount > 0) { + message.warning(`${successCount} 个成功,${failCount} 个失败`); + } else if (failCount > 0) { + message.error(`${failCount} 个文件上传失败`); } }; + // 移除队列中的文件 + const removeFromQueue = (uid: string) => { + setUploadQueue(prev => prev.filter(item => item.uid !== uid)); + }; + + // 清空队列 + const clearQueue = () => { + setUploadQueue([]); + }; + + // 获取状态图标 + const getStatusIcon = (status: UploadFileStatus['status']) => { + switch (status) { + case 'waiting': + return ; + case 'uploading': + return ; + case 'success': + return ; + case 'error': + return ; + } + }; + + const waitingCount = uploadQueue.filter(f => f.status === 'waiting').length; + const successCount = uploadQueue.filter(f => f.status === 'success').length; + return ( 0 ? 16 : 0 }} >

- {isAtLimit ? `已达到文档数量上限(${maxDocuments}个)` : '点击或拖拽文件到此区域上传'} + {isAtLimit + ? `已达到文档数量上限(${maxDocuments}个)` + : isProcessing + ? '正在上传中,请稍候...' + : '点击或拖拽文件到此区域批量上传'}

支持格式:PDF、DOC、DOCX、TXT、MD | 单个文件最大10MB

+

+ ⚠️ 系统会自动过滤重名文件,避免重复上传 +

- 当前已上传: {currentDocumentCount}/{maxDocuments} 个文档 + 当前已上传: {currentDocumentCount}/{maxDocuments} 个文档(还可上传 {remainingSlots} 个)

- {uploading && ( + {/* 上传队列 */} + {uploadQueue.length > 0 && (
- -

- {uploadProgress < 100 ? '正在上传...' : '上传完成,正在处理...'} -

+
+ + 上传队列 + + ({successCount} 成功 / {uploadQueue.length} 总计) + + +
+ {waitingCount > 0 && !isProcessing && ( + + )} + +
+
+ +
+ {uploadQueue.map((item) => ( +
+ {/* 状态图标 */} +
+ {getStatusIcon(item.status)} +
+ + {/* 文件信息 */} +
+
+ + + {item.name} + + + {formatFileSize(item.size)} + +
+ + {/* 上传进度 */} + {item.status === 'uploading' && ( + + )} + + {/* 错误信息 */} + {item.status === 'error' && item.errorMessage && ( +
+ {item.errorMessage} +
+ )} +
+ + {/* 删除按钮 */} + {(item.status === 'waiting' || item.status === 'error') && !isProcessing && ( +
+ ))} +
)}
@@ -141,4 +398,3 @@ const DocumentUpload: React.FC = ({ }; export default DocumentUpload; - diff --git a/frontend-v2/src/modules/pkb/components/Workspace/BatchModeComplete.tsx b/frontend-v2/src/modules/pkb/components/Workspace/BatchModeComplete.tsx index 869d3aa5..ab6ebc65 100644 --- a/frontend-v2/src/modules/pkb/components/Workspace/BatchModeComplete.tsx +++ b/frontend-v2/src/modules/pkb/components/Workspace/BatchModeComplete.tsx @@ -7,6 +7,7 @@ import React, { useState, useEffect } from 'react'; import { Button, Table, Progress, message, Card, Steps, Checkbox, Radio, Tooltip } from 'antd'; import { Play, Download, RotateCw, FileText, CheckCircle2, Zap } from 'lucide-react'; import type { KnowledgeBase, Document } from '../../api/knowledgeBaseApi'; +import { getAccessToken } from '../../../../framework/auth/api'; interface BatchModeCompleteProps { kbId: string; @@ -137,9 +138,13 @@ export const BatchModeComplete: React.FC = ({ // 调用批处理API(使用v2新版API) // 完整路径: /api/v2/pkb/batch-tasks/batch/execute // 请求体格式必须匹配后端 ExecuteBatchBody 接口 + const token = getAccessToken(); const response = await fetch('/api/v2/pkb/batch-tasks/batch/execute', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}), + }, body: JSON.stringify({ kb_id: kbId, // 后端期望 kb_id document_ids: selectedDocs, // 后端期望 document_ids @@ -174,7 +179,10 @@ export const BatchModeComplete: React.FC = ({ // 轮询任务状态 const pollInterval = setInterval(async () => { try { - const statusRes = await fetch(`/api/v2/pkb/batch-tasks/batch/tasks/${taskId}`); + const pollToken = getAccessToken(); + const statusRes = await fetch(`/api/v2/pkb/batch-tasks/batch/tasks/${taskId}`, { + headers: pollToken ? { 'Authorization': `Bearer ${pollToken}` } : {}, + }); if (!statusRes.ok) { console.error('[BatchMode] 获取任务状态失败:', statusRes.status); return; @@ -211,7 +219,10 @@ export const BatchModeComplete: React.FC = ({ // 获取最终结果 try { - const resultsRes = await fetch(`/api/v2/pkb/batch-tasks/batch/tasks/${taskId}/results`); + const resultToken = getAccessToken(); + const resultsRes = await fetch(`/api/v2/pkb/batch-tasks/batch/tasks/${taskId}/results`, { + headers: resultToken ? { 'Authorization': `Bearer ${resultToken}` } : {}, + }); console.log('[BatchMode] 获取结果响应状态:', resultsRes.status); if (resultsRes.ok) { diff --git a/frontend-v2/src/modules/pkb/components/Workspace/DeepReadMode.tsx b/frontend-v2/src/modules/pkb/components/Workspace/DeepReadMode.tsx index 5ff037d1..ac9ab998 100644 --- a/frontend-v2/src/modules/pkb/components/Workspace/DeepReadMode.tsx +++ b/frontend-v2/src/modules/pkb/components/Workspace/DeepReadMode.tsx @@ -7,6 +7,7 @@ import React, { useMemo } from 'react'; import { FileText, BookOpen, ExternalLink } from 'lucide-react'; import { ChatContainer } from '@/shared/components/Chat'; import type { KnowledgeBase, Document } from '../../api/knowledgeBaseApi'; +import { getAccessToken } from '../../../../framework/auth/api'; interface DeepReadModeProps { kbId: string; @@ -144,16 +145,18 @@ export const DeepReadMode: React.FC = ({ timestamp: Date.now(), }]} providerConfig={{ - apiEndpoint: '/api/v1/chat/stream', + apiEndpoint: '/api/v2/pkb/chat/stream', requestFn: async (message: string) => { // 🔑 关键:传递 fullTextDocumentIds 而不是 documentIds // fullTextDocumentIds 会触发全文加载模式,AI可以看到完整文献 // documentIds 只是过滤RAG检索结果,AI只能看到片段 - const response = await fetch('/api/v1/chat/stream', { + const token = getAccessToken(); + const response = await fetch('/api/v2/pkb/chat/stream', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'text/event-stream', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}), }, body: JSON.stringify({ content: message, diff --git a/frontend-v2/src/modules/pkb/components/Workspace/FullTextMode.tsx b/frontend-v2/src/modules/pkb/components/Workspace/FullTextMode.tsx index f2f296fd..8670b6f0 100644 --- a/frontend-v2/src/modules/pkb/components/Workspace/FullTextMode.tsx +++ b/frontend-v2/src/modules/pkb/components/Workspace/FullTextMode.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { BookOpen, FileText } from 'lucide-react'; import { ChatContainer } from '@/shared/components/Chat'; import type { KnowledgeBase, Document } from '../../api/knowledgeBaseApi'; +import { getAccessToken } from '../../../../framework/auth/api'; interface FullTextModeProps { kbId: string; @@ -111,13 +112,15 @@ export const FullTextMode: React.FC = ({ kbId, documents }) = }]} customMessageRenderer={renderMessageContent} providerConfig={{ - apiEndpoint: '/api/v1/chat/stream', + apiEndpoint: '/api/v2/pkb/chat/stream', requestFn: async (message: string) => { - const response = await fetch('/api/v1/chat/stream', { + const token = getAccessToken(); + const response = await fetch('/api/v2/pkb/chat/stream', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'text/event-stream', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}), }, body: JSON.stringify({ content: message, diff --git a/frontend-v2/src/modules/pkb/pages/DashboardPage.tsx b/frontend-v2/src/modules/pkb/pages/DashboardPage.tsx index 2814d8ea..5a1605d3 100644 --- a/frontend-v2/src/modules/pkb/pages/DashboardPage.tsx +++ b/frontend-v2/src/modules/pkb/pages/DashboardPage.tsx @@ -6,6 +6,7 @@ import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useKnowledgeBaseStore } from '../stores/useKnowledgeBaseStore'; +import DocumentUpload from '../components/DocumentUpload'; import { Plus, BookOpen, Microscope, Stethoscope, Pill, GraduationCap, Wrench, MessageSquare, FileText, @@ -85,6 +86,9 @@ const DashboardPage: React.FC = () => { // 表单数据 const [formData, setFormData] = useState({ name: '', department: 'Cardiology' }); const [files, setFiles] = useState([]); + // 新增:创建知识库后保存ID,用于Step3上传文档 + const [createdKbId, setCreatedKbId] = useState(null); + const [uploadedCount, setUploadedCount] = useState(0); useEffect(() => { fetchKnowledgeBases(); @@ -97,22 +101,34 @@ const DashboardPage: React.FC = () => { setSelectedTypeId(null); setFormData({ name: '', department: 'Cardiology' }); setFiles([]); + setCreatedKbId(null); + setUploadedCount(0); setIsModalOpen(true); }; - const handleCreateSubmit = async () => { + // Step 2 完成后,创建知识库并进入Step 3 + const handleStep2Next = async () => { + if (!formData.name) return; + try { - // 后端期望 description 字段,将 department 作为描述的一部分 const description = `${formData.department || ''}科 知识库`; const kb = await createKnowledgeBase(formData.name, description); - message.success('知识库创建成功!'); - setIsModalOpen(false); - navigate(`/knowledge-base/workspace/${kb.id}`); + setCreatedKbId(kb.id); + message.success('知识库创建成功!现在可以上传文档'); + setCreateStep(3); } catch (error: any) { message.error(error.message || '创建失败'); } }; + // Step 3 完成后,进入工作台 + const handleCreateSubmit = async () => { + if (createdKbId) { + setIsModalOpen(false); + navigate(`/knowledge-base/workspace/${createdKbId}`); + } + }; + // 删除模拟上传功能,Step 3留作后续实现真实上传组件 const getStatusText = (status: string) => { @@ -324,57 +340,47 @@ const DashboardPage: React.FC = () => { )} {/* Step 3: 上传 */} - {createStep === 3 && ( + {createStep === 3 && createdKbId && (
-
-
- + {/* 成功提示 */} +
+ +
+

知识库创建成功!

+

现在可以上传文档,或点击"完成"跳过此步骤稍后上传。

-

上传知识资产

-

知识库创建后,可在工作台中上传文档

-

💡 提示:点击下方"完成"按钮进入工作台,在"知识资产"Tab中上传PDF文档

- {files.length > 0 && ( -
-
- 上传队列 ({files.length}) -
-
- {files.map(f => ( -
-
- -
-
-
- {f.name} - {f.size} -
-
-
-
-
- - {f.status !== 'ready' && } - {getStatusText(f.status)} - - {f.progress}% -
-
- -
- ))} + {/* 真实的上传组件 */} + { + setUploadedCount(prev => prev + 1); + message.success('文档上传成功!'); + }} + maxDocuments={50} + currentDocumentCount={uploadedCount} + /> + + {/* 上传统计 */} + {uploadedCount > 0 && ( +
+
+ + + 已上传 {uploadedCount} 个文档 +
+ + 系统正在后台处理,可继续上传 +
)} + + {/* 提示信息 */} +

+ 💡 您也可以跳过此步骤,稍后在工作台的"知识资产"Tab中上传文档 +

)}
@@ -382,30 +388,47 @@ const DashboardPage: React.FC = () => { {/* Modal Footer */}
- {createStep < 3 ? ( + {createStep === 1 && ( - ) : ( + )} + + {createStep === 2 && ( + + )} + + {createStep === 3 && (