Files
aurak/web/types.ts
T
Developer 46a10ba091 P2全部完成: 尝试限制/预约时段/题目回顾/随机排序
后端:
- assessment-template entity: attemptLimit/scheduledStart/End/reviewMode/shuffleQuestions
- DTO 更新: 新增 P2 字段验证
- startSession: 尝试次数检查、预约时段检查、题目随机排序
- getSessionState: reviewMode 控制答案可见性
- 新增 GET /assessment/:id/review 回顾端点

前端:
- AssessmentTemplateManager: 新增尝试次数/答题回顾/题目排序/预约时段配置
- AssessmentView: 答题回顾按钮(完成页)+提交确认弹窗+标记回头功能
- types.ts: 新增 P2 字段类型
- assessmentService: 新增 getReview 方法
- 进度导航点: 可视化题序+标记状态

测试 20项全部通过 + 系统测试 142项全部通过 

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:57:32 +08:00

437 lines
9.9 KiB
TypeScript

export interface IndexingConfig {
chunkSize: number;
chunkOverlap: number;
embeddingModelId: string;
mode?: 'fast' | 'precise'; // Processing mode: fast/precise
groupIds?: string[]; // Groups to associate with the file upon upload
}
export interface VisionAnalysisResult {
text: string; // Extracted text content
images: ImageDescription[]; // Image descriptions
layout: string; // Layout type
confidence: number; // 信頼度 (0-1)
pageIndex?: number; // Page number
}
export interface ImageDescription {
type: string; // Image type (graph/diagram/flowchart etc.)
description: string; // Detailed description
position?: number; // Position within the page
}
export interface PipelineResult {
success: boolean;
fileId: string;
fileName: string;
totalPages: number;
processedPages: number;
failedPages: number;
results: VisionAnalysisResult[];
cost: number; // Cost (USD)
duration: number; // Duration (seconds)
mode: 'precise';
}
export interface ModeRecommendation {
recommendedMode: 'precise' | 'fast';
reason: string;
estimatedCost?: number; // Estimated cost (USD)
estimatedTime?: number; // Estimated time (seconds)
warnings?: string[];
}
// Type definitions for knowledge base extensions
export interface KnowledgeGroup {
id: string;
name: string;
description?: string;
color: string;
fileCount: number;
parentId?: string | null;
children?: KnowledgeGroup[];
createdAt: string;
updatedAt?: string;
}
export interface CreateGroupData {
name: string;
description?: string;
color?: string;
parentId?: string | null;
}
export interface UpdateGroupData {
name?: string;
description?: string;
color?: string;
parentId?: string | null;
}
export interface KnowledgeFile {
id: string;
name: string;
originalName: string;
title?: string;
content?: string;
size: number;
type: string;
status: 'pending' | 'indexing' | 'extracted' | 'vectorized' | 'failed' | 'ready' | 'error';
groups?: KnowledgeGroup[];
createdAt: string;
updatedAt: string;
}
export interface SearchHistoryItem {
id: string;
title: string;
selectedGroups: string[] | null;
messageCount: number;
lastMessageAt: string;
createdAt: string;
}
export interface SearchHistoryDetail {
id: string;
title: string;
selectedGroups: string[] | null;
messages: Array<{
id: string;
role: 'user' | 'assistant';
content: string;
sources?: Array<{
fileName: string;
content: string;
score: number;
chunkIndex: number;
}>;
createdAt: string;
}>;
}
export interface PDFStatus {
status: 'pending' | 'converting' | 'ready' | 'failed';
pdfPath?: string;
error?: string;
}
export interface NoteCategory {
id: string
name: string
parentId?: string
level: number
userId: string
tenantId: string
createdAt: string
updatedAt: string
}
export interface Note {
id: string;
title: string;
content: string;
userId: string;
tenantId?: string;
groupId?: string;
categoryId?: string;
sharingStatus: 'PRIVATE' | 'TENANT' | 'GLOBAL_PENDING' | 'GLOBAL_APPROVED';
createdAt: string;
updatedAt: string;
user?: {
id: string;
username: string;
name?: string;
};
}
export interface RawFile {
name: string;
type: string;
size: number;
content: string;
preview?: string;
file: File; // Keep original file for upload
isNote?: boolean;
textContent?: string;
}
export enum Role {
USER = 'user',
MODEL = 'model',
}
export interface Message {
id: string;
role: Role;
text: string;
timestamp: number;
isError?: boolean;
sources?: ChatSource[];
}
export interface ChatSource {
fileName: string;
title?: string;
content: string;
score: number;
chunkIndex: number;
fileId?: string;
}
export interface ChatState {
messages: Message[];
isLoading: boolean;
}
export type Language = 'ja' | 'en' | 'zh';
export enum ModelType {
// Changed from type to enum
LLM = "llm",
EMBEDDING = "embedding",
RERANK = "rerank",
VISION = "vision",
}
// 1. Model Definition (The "Provider" setup)
export interface ModelConfig {
id: string;
name: string; // Display name, e.g. "My DeepSeek"
modelId: string; // The actual string ID sent to API, e.g., "gpt-4o"
baseUrl?: string; // Base URL for OpenAI compatible API
apiKey?: string; // API key for the service
type: ModelType;
dimensions?: number; // Vector dimensions of the embedding model
supportsVision?: boolean; // Whether it supports vision capabilities
// ==================== Additional Fields ====================
/**
* Model's input token limit
* e.g., OpenAI=8191, Gemini=2048
*/
maxInputTokens?: number;
/**
* Batch processing limit (maximum number of inputs per request)
* e.g., OpenAI=2048, Gemini=100
*/
maxBatchSize?: number;
/**
* Whether it is a vector model (for identification in system settings)
*/
isVectorModel?: boolean;
/**
* Model provider name (for display)
* e.g., "OpenAI", "Google Gemini", "Custom"
*/
providerName?: string;
/**
* Whether it is enabled
*/
isEnabled?: boolean;
/**
* Whether to use this model as the default
*/
isDefault?: boolean;
}
// 2. Application Logic Settings (The "App" setup)
export interface AppSettings {
// References to ModelConfig IDs
selectedLLMId: string;
selectedEmbeddingId: string; // Default for new uploads, and used for query encoding
selectedRerankId: string;
// Model Hyperparameters
temperature: number;
maxTokens: number;
// Retrieval
enableRerank: boolean;
topK: number;
similarityThreshold: number; // Similarity threshold for vector search
rerankSimilarityThreshold: number; // Similarity threshold for reranking
enableFullTextSearch: boolean; // Whether to enable full-text search
hybridVectorWeight: number; // Vector weight for hybrid search
// Search Enhancement
enableQueryExpansion: boolean;
enableHyDE: boolean;
chunkSize?: number;
chunkOverlap?: number;
// Language
language?: string;
// Coach
coachKbId?: string;
// Vision
selectedVisionId?: string;
}
// Default Models (Frontend specific)
export const DEFAULT_MODELS: ModelConfig[] = [];
export const DEFAULT_SETTINGS: AppSettings = {
selectedLLMId: '',
selectedEmbeddingId: '',
selectedRerankId: '',
selectedVisionId: '',
temperature: 0.3,
maxTokens: 8192,
enableRerank: false,
topK: 4,
similarityThreshold: 0.3, // Default similarity threshold for vector search
rerankSimilarityThreshold: 0.5, // Default similarity threshold for reranking
enableFullTextSearch: false, // Turn off full-text search by default
hybridVectorWeight: 0.7, // Vector weight for hybrid search
enableQueryExpansion: false,
enableHyDE: false,
chunkSize: 1000,
chunkOverlap: 100,
language: 'ja',
};
export const API_BASE_URL = '/api'
export interface Tenant {
id: string;
name: string;
domain?: string;
parentId?: string | null;
children?: Tenant[];
members?: TenantMember[];
settings_obj?: any;
createdAt: string;
updatedAt: string;
}
export interface TenantMember {
id: string;
userId: string;
tenantId: string;
role: string;
user?: {
id: string;
username: string;
displayName?: string;
email?: string;
};
createdAt: string;
updatedAt: string;
}
// Assessment Template Types
export interface AssessmentDimension {
name: string;
label: string;
weight: number;
}
export interface AssessmentTemplate {
id: string;
name: string;
description?: string;
keywords?: string[];
questionCount: number;
difficultyDistribution?: Record<string, number>;
style?: string;
knowledgeBaseId?: string;
knowledgeGroupId?: string;
knowledgeGroup?: KnowledgeGroup;
dimensions?: AssessmentDimension[];
passingScore?: number;
totalTimeLimit?: number;
perQuestionTimeLimit?: number;
/** P2: Max attempts (0=unlimited) */
attemptLimit?: number;
/** P2: Scheduled window */
scheduledStart?: string | null;
scheduledEnd?: string | null;
/** P2: Review mode */
reviewMode?: string;
/** P2: Shuffle questions */
shuffleQuestions?: boolean;
isActive: boolean;
version: number;
creatorId: string;
createdAt: string;
updatedAt: string;
}
export interface CreateTemplateData {
name: string;
description?: string;
keywords?: string[];
questionCount?: number;
difficultyDistribution?: Record<string, number>;
style?: string;
knowledgeBaseId?: string;
knowledgeGroupId?: string;
dimensions?: AssessmentDimension[];
passingScore?: number;
totalTimeLimit?: number;
perQuestionTimeLimit?: number;
/** P2 */
attemptLimit?: number;
scheduledStart?: string | null;
scheduledEnd?: string | null;
reviewMode?: string;
shuffleQuestions?: boolean;
}
export interface UpdateTemplateData extends Partial<CreateTemplateData> {
isActive?: boolean;
}
export interface QuestionBank {
id: string;
name: string;
description?: string;
status: 'DRAFT' | 'PENDING_REVIEW' | 'PUBLISHED' | 'REJECTED';
templateId?: string | null;
createdAt: string;
updatedAt: string;
}
export interface QuestionBankItem {
id: string;
bankId: string;
questionText: string;
questionType: 'SHORT_ANSWER' | 'MULTIPLE_CHOICE' | 'TRUE_FALSE';
options?: string[] | null;
correctAnswer?: string | null;
keyPoints: string[];
difficulty: 'STANDARD' | 'ADVANCED' | 'SPECIALIST';
dimension: 'PROMPT' | 'LLM' | 'IDE' | 'DEV_PATTERN' | 'WORK_CAPABILITY';
basis?: string | null;
status: 'PENDING_REVIEW' | 'PUBLISHED';
createdAt: string;
}
export interface CreateQuestionBankData {
name: string;
description?: string;
templateId?: string;
}
export interface CreateQuestionBankItemData {
questionText: string;
questionType: 'SHORT_ANSWER' | 'MULTIPLE_CHOICE' | 'TRUE_FALSE';
options?: string[];
correctAnswer?: string;
keyPoints: string[];
difficulty: 'STANDARD' | 'ADVANCED' | 'SPECIALIST';
dimension: 'PROMPT' | 'LLM' | 'IDE' | 'DEV_PATTERN' | 'WORK_CAPABILITY';
}