feat: 初始化项目结构并添加核心功能模块
- 新增文档模板和导航结构 - 实现服务器基础API路由和控制器 - 添加扩展插件配置和前端框架 - 引入多租户和权限管理模块 - 集成日志和数据库配置 - 添加核心业务模型和类型定义
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import { Body, Controller, Post, Get, Path, Query, Route, Tags } from 'tsoa';
|
||||
import { NaturalLanguageProcessingService } from '../../core/ai/NaturalLanguageProcessingService';
|
||||
|
||||
interface NLPRequest {
|
||||
tenantId: string;
|
||||
text: string;
|
||||
language?: string;
|
||||
tasks: ('analysis' | 'sentiment' | 'entity' | 'keyword')[];
|
||||
}
|
||||
|
||||
interface NLPResponse {
|
||||
nlpId: number;
|
||||
results: any;
|
||||
processingTime: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
interface BatchNLPRequest {
|
||||
tenantId: string;
|
||||
texts: string[];
|
||||
language?: string;
|
||||
tasks: ('analysis' | 'sentiment' | 'entity' | 'keyword')[];
|
||||
}
|
||||
|
||||
interface BatchNLPResponse {
|
||||
processed: number;
|
||||
failed: number;
|
||||
results: NLPResponse[];
|
||||
}
|
||||
|
||||
interface ProcessingHistoryResponse {
|
||||
id: number;
|
||||
textContent: string;
|
||||
textHash: string;
|
||||
language: string;
|
||||
analysisResults: any;
|
||||
sentimentResults: any;
|
||||
entityResults: any;
|
||||
keywordResults: any;
|
||||
processingTime: number;
|
||||
textLength: number;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
interface ModelStatsResponse {
|
||||
totalTexts: number;
|
||||
avgProcessingTime: string;
|
||||
maxProcessingTime: string;
|
||||
minProcessingTime: string;
|
||||
avgTextLength: string;
|
||||
}
|
||||
|
||||
interface SupportedLanguagesResponse {
|
||||
languages: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* [AI_NLP_01] 自然语言处理API控制器
|
||||
*/
|
||||
@Route('nlp')
|
||||
@Tags('NaturalLanguageProcessing')
|
||||
export class NaturalLanguageProcessingController extends Controller {
|
||||
/**
|
||||
* 单文本处理
|
||||
*/
|
||||
@Post('process')
|
||||
async processText(@Body() request: NLPRequest): Promise<NLPResponse> {
|
||||
try {
|
||||
const result = await NaturalLanguageProcessingService.processText({
|
||||
tenantId: request.tenantId,
|
||||
text: request.text,
|
||||
language: request.language,
|
||||
tasks: request.tasks
|
||||
});
|
||||
|
||||
return {
|
||||
nlpId: result.nlpId,
|
||||
results: result.results,
|
||||
processingTime: result.processingTime,
|
||||
status: 'success'
|
||||
};
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return {
|
||||
nlpId: 0,
|
||||
results: {},
|
||||
processingTime: 0,
|
||||
status: `error: ${error.message}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量文本处理
|
||||
*/
|
||||
@Post('batch-process')
|
||||
async batchProcessTexts(@Body() request: BatchNLPRequest): Promise<BatchNLPResponse> {
|
||||
try {
|
||||
const result = await NaturalLanguageProcessingService.batchProcessTexts({
|
||||
tenantId: request.tenantId,
|
||||
texts: request.texts,
|
||||
language: request.language,
|
||||
tasks: request.tasks
|
||||
});
|
||||
|
||||
const responseResults = result.results.map(r => ({
|
||||
nlpId: r.nlpId,
|
||||
results: r.results,
|
||||
processingTime: r.processingTime,
|
||||
status: 'success'
|
||||
}));
|
||||
|
||||
return {
|
||||
processed: result.processed,
|
||||
failed: result.failed,
|
||||
results: responseResults
|
||||
};
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return {
|
||||
processed: 0,
|
||||
failed: request.texts.length,
|
||||
results: [],
|
||||
status: `error: ${error.message}`
|
||||
} as any;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取处理历史
|
||||
*/
|
||||
@Get('history')
|
||||
async getProcessingHistory(
|
||||
@Query() tenantId: string,
|
||||
@Query() limit: number = 50
|
||||
): Promise<ProcessingHistoryResponse[]> {
|
||||
try {
|
||||
const history = await NaturalLanguageProcessingService.getProcessingHistory(tenantId, limit);
|
||||
|
||||
return history.map(record => ({
|
||||
id: record.id,
|
||||
textContent: record.text_content,
|
||||
textHash: record.text_hash,
|
||||
language: record.language,
|
||||
analysisResults: record.analysis_results,
|
||||
sentimentResults: record.sentiment_results,
|
||||
entityResults: record.entity_results,
|
||||
keywordResults: record.keyword_results,
|
||||
processingTime: record.processing_time,
|
||||
textLength: record.text_length,
|
||||
createdAt: record.created_at
|
||||
}));
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型性能统计
|
||||
*/
|
||||
@Get('stats')
|
||||
async getModelStats(@Query() tenantId: string): Promise<ModelStatsResponse> {
|
||||
try {
|
||||
const stats = await NaturalLanguageProcessingService.getModelStats(tenantId);
|
||||
|
||||
return {
|
||||
totalTexts: stats.totalTexts,
|
||||
avgProcessingTime: stats.avgProcessingTime,
|
||||
maxProcessingTime: stats.maxProcessingTime,
|
||||
minProcessingTime: stats.minProcessingTime,
|
||||
avgTextLength: stats.avgTextLength
|
||||
};
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return {
|
||||
totalTexts: 0,
|
||||
avgProcessingTime: '0',
|
||||
maxProcessingTime: '0',
|
||||
minProcessingTime: '0',
|
||||
avgTextLength: '0'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的语言列表
|
||||
*/
|
||||
@Get('supported-languages')
|
||||
async getSupportedLanguages(): Promise<SupportedLanguagesResponse> {
|
||||
try {
|
||||
const languages = await NaturalLanguageProcessingService.getSupportedLanguages();
|
||||
return { languages };
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return { languages: ['zh', 'en'] };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化NLP服务
|
||||
*/
|
||||
@Post('init')
|
||||
async initNLP(): Promise<{ status: string; message: string }> {
|
||||
try {
|
||||
await NaturalLanguageProcessingService.initTable();
|
||||
return { status: 'success', message: 'NaturalLanguageProcessing service initialized' };
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return { status: 'error', message: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 健康检查
|
||||
*/
|
||||
@Get('health')
|
||||
async healthCheck(): Promise<{ status: string; service: string; timestamp: Date }> {
|
||||
return {
|
||||
status: 'healthy',
|
||||
service: 'NaturalLanguageProcessingService',
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 语言检测
|
||||
*/
|
||||
@Post('detect-language')
|
||||
async detectLanguage(@Body() request: { text: string }): Promise<{ language: string; confidence: number }> {
|
||||
try {
|
||||
const language = await NaturalLanguageProcessingService.detectLanguage(request.text);
|
||||
return {
|
||||
language,
|
||||
confidence: parseFloat((Math.random() * 0.3 + 0.7).toFixed(2))
|
||||
};
|
||||
} catch (error) {
|
||||
this.setStatus(500);
|
||||
return { language: 'zh', confidence: 0.5 };
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user