Files
AIclinicalresearch/backend/scripts/test-pkb-apis-simple.ts
HaHafeng 4088275290 fix(pkb): fix create KB and upload issues - remove simulated upload, fix department mapping, add upload modal
Fixed issues:
- Remove simulateUpload function from DashboardPage Step 3
- Map department to description field when creating KB
- Add upload modal in WorkspacePage knowledge assets tab
- Fix DocumentUpload import path (../../stores to ../stores)

Known issue: Dify API validation error during document upload (file uploaded but DB record failed, needs investigation)

Testing: KB creation works, upload dialog opens correctly
2026-01-13 13:17:20 +08:00

337 lines
10 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* PKB模块API简化测试脚本
* 测试现有知识库的各项功能
*/
import axios from 'axios';
const BASE_URL = 'http://localhost:3000';
interface TestResult {
name: string;
status: 'pass' | 'fail';
message: string;
duration?: number;
}
const results: TestResult[] = [];
function printResult(result: TestResult) {
const icon = result.status === 'pass' ? '✅' : '❌';
console.log(`${icon} ${result.name} ${result.duration ? `(${result.duration}ms)` : ''}`);
console.log(` ${result.message}`);
}
// 测试1健康检查
async function testHealthCheck(): Promise<TestResult> {
const startTime = Date.now();
try {
const response = await axios.get(`${BASE_URL}/api/v2/pkb/health`);
const duration = Date.now() - startTime;
if (response.data.status === 'ok') {
return {
name: '健康检查v2',
status: 'pass',
message: `知识库数: ${response.data.database.knowledgeBases}, schema: ${response.data.database.schema}`,
duration,
};
} else {
return {
name: '健康检查v2',
status: 'fail',
message: '返回状态异常',
duration,
};
}
} catch (error: any) {
return {
name: '健康检查v2',
status: 'fail',
message: error.message,
duration: Date.now() - startTime,
};
}
}
// 测试2获取知识库列表v1 vs v2
async function testGetKnowledgeBases(): Promise<TestResult> {
try {
const startV1 = Date.now();
const v1Response = await axios.get(`${BASE_URL}/api/v1/knowledge-bases`);
const v1Duration = Date.now() - startV1;
const startV2 = Date.now();
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases`);
const v2Duration = Date.now() - startV2;
const v1Count = v1Response.data.data?.length || 0;
const v2Count = v2Response.data.data?.length || 0;
if (v1Count === v2Count) {
return {
name: '获取知识库列表v1 vs v2',
status: 'pass',
message: `v1: ${v1Count}个 (${v1Duration}ms), v2: ${v2Count}个 (${v2Duration}ms) ✅`,
duration: v1Duration + v2Duration,
};
} else {
return {
name: '获取知识库列表v1 vs v2',
status: 'fail',
message: `数量不一致v1: ${v1Count}, v2: ${v2Count}`,
duration: v1Duration + v2Duration,
};
}
} catch (error: any) {
return {
name: '获取知识库列表v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 测试3获取知识库详情v1 vs v2
async function testGetKnowledgeBaseById(kbId: string): Promise<TestResult> {
try {
const startV1 = Date.now();
const v1Response = await axios.get(`${BASE_URL}/api/v1/knowledge-bases/${kbId}`);
const v1Duration = Date.now() - startV1;
const startV2 = Date.now();
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases/${kbId}`);
const v2Duration = Date.now() - startV2;
const v1Name = v1Response.data.data?.name;
const v2Name = v2Response.data.data?.name;
if (v1Name === v2Name) {
return {
name: '获取知识库详情v1 vs v2',
status: 'pass',
message: `名称一致: "${v1Name}", v1: ${v1Duration}ms, v2: ${v2Duration}ms ✅`,
duration: v1Duration + v2Duration,
};
} else {
return {
name: '获取知识库详情v1 vs v2',
status: 'fail',
message: `名称不一致v1: "${v1Name}", v2: "${v2Name}"`,
duration: v1Duration + v2Duration,
};
}
} catch (error: any) {
return {
name: '获取知识库详情v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 测试4获取知识库统计v1 vs v2
async function testGetKnowledgeBaseStats(kbId: string): Promise<TestResult> {
try {
const v1Response = await axios.get(`${BASE_URL}/api/v1/knowledge-bases/${kbId}/stats`);
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases/${kbId}/stats`);
const v1Docs = v1Response.data.data.totalDocuments;
const v2Docs = v2Response.data.data.totalDocuments;
if (v1Docs === v2Docs) {
return {
name: '获取知识库统计v1 vs v2',
status: 'pass',
message: `文档数一致: ${v1Docs}个 ✅`,
};
} else {
return {
name: '获取知识库统计v1 vs v2',
status: 'fail',
message: `文档数不一致v1: ${v1Docs}, v2: ${v2Docs}`,
};
}
} catch (error: any) {
return {
name: '获取知识库统计v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 测试5RAG检索v1 vs v2
async function testSearchKnowledgeBase(kbId: string): Promise<TestResult> {
try {
const query = '治疗';
const v1Response = await axios.get(`${BASE_URL}/api/v1/knowledge-bases/${kbId}/search`, {
params: { query, top_k: 3 },
});
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases/${kbId}/search`, {
params: { query, top_k: 3 },
});
const v1Count = v1Response.data.data?.records?.length || 0;
const v2Count = v2Response.data.data?.records?.length || 0;
return {
name: 'RAG检索v1 vs v2',
status: 'pass',
message: `v1返回${v1Count}条, v2返回${v2Count}条 ✅`,
};
} catch (error: any) {
return {
name: 'RAG检索v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 测试6文档选择全文阅读模式
async function testDocumentSelection(kbId: string): Promise<TestResult> {
try {
const v1Response = await axios.get(`${BASE_URL}/api/v1/knowledge-bases/${kbId}/document-selection`, {
params: { max_files: 5, max_tokens: 100000 },
});
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases/${kbId}/document-selection`, {
params: { max_files: 5, max_tokens: 100000 },
});
const v1Docs = v1Response.data.data?.selectedDocuments?.length || 0;
const v2Docs = v2Response.data.data?.selectedDocuments?.length || 0;
return {
name: '文档选择-全文阅读模式v1 vs v2',
status: 'pass',
message: `v1选择${v1Docs}个文档, v2选择${v2Docs}个文档 ✅`,
};
} catch (error: any) {
return {
name: '文档选择-全文阅读模式v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 测试7批处理模板
async function testBatchTemplates(): Promise<TestResult> {
try {
const v1Response = await axios.get(`${BASE_URL}/api/v1/batch/templates`);
const v2Response = await axios.get(`${BASE_URL}/api/v2/pkb/batch-tasks/batch/templates`);
const v1Count = v1Response.data.data?.length || 0;
const v2Count = v2Response.data.data?.length || 0;
return {
name: '批处理模板v1 vs v2',
status: 'pass',
message: `v1: ${v1Count}个模板, v2: ${v2Count}个模板 ✅`,
};
} catch (error: any) {
return {
name: '批处理模板v1 vs v2',
status: 'fail',
message: error.message,
};
}
}
// 主测试函数
async function runTests() {
console.log('🚀 PKB API测试开始...\n');
console.log('='.repeat(80));
// 测试1健康检查
console.log('\n📋 测试1健康检查');
console.log('-'.repeat(80));
results.push(await testHealthCheck());
printResult(results[results.length - 1]);
// 测试2获取知识库列表
console.log('\n📋 测试2知识库列表');
console.log('-'.repeat(80));
results.push(await testGetKnowledgeBases());
printResult(results[results.length - 1]);
// 获取第一个知识库ID用于后续测试
const kbListResponse = await axios.get(`${BASE_URL}/api/v2/pkb/knowledge/knowledge-bases`);
const firstKb = kbListResponse.data.data?.[0];
if (!firstKb) {
console.log('\n❌ 没有可用的知识库,后续测试跳过');
return;
}
const kbId = firstKb.id;
console.log(`\n使用知识库: ${firstKb.name} (ID: ${kbId})`);
// 测试3获取知识库详情
console.log('\n📋 测试3知识库详情');
console.log('-'.repeat(80));
results.push(await testGetKnowledgeBaseById(kbId));
printResult(results[results.length - 1]);
// 测试4知识库统计
console.log('\n📋 测试4知识库统计');
console.log('-'.repeat(80));
results.push(await testGetKnowledgeBaseStats(kbId));
printResult(results[results.length - 1]);
// 测试5RAG检索
console.log('\n📋 测试5RAG检索');
console.log('-'.repeat(80));
results.push(await testSearchKnowledgeBase(kbId));
printResult(results[results.length - 1]);
// 测试6文档选择
console.log('\n📋 测试6文档选择全文阅读');
console.log('-'.repeat(80));
results.push(await testDocumentSelection(kbId));
printResult(results[results.length - 1]);
// 测试7批处理模板
console.log('\n📋 测试7批处理模板');
console.log('-'.repeat(80));
results.push(await testBatchTemplates());
printResult(results[results.length - 1]);
// 总结
console.log('\n' + '='.repeat(80));
console.log('📊 测试总结');
console.log('='.repeat(80));
const passCount = results.filter(r => r.status === 'pass').length;
const failCount = results.filter(r => r.status === 'fail').length;
const totalDuration = results.reduce((sum, r) => sum + (r.duration || 0), 0);
console.log(`\n总计: ${results.length}个测试`);
console.log(`✅ 通过: ${passCount}`);
console.log(`❌ 失败: ${failCount}`);
console.log(`⏱️ 总耗时: ${totalDuration}ms`);
if (failCount === 0) {
console.log('\n🎉 所有测试通过v1和v2功能完全一致');
} else {
console.log('\n⚠ 部分测试失败,请查看详情');
}
}
runTests().catch(error => {
console.error('❌ 测试执行失败:', error);
process.exit(1);
});