import { Component, OnInit, OnDestroy } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Subscription } from 'rxjs'; import { RequirementMappingService } from '../../services/requirement-mapping.service'; import { ColorAnalysisService, ColorAnalysisResult } from '../../shared/services/color-analysis.service'; import { RequirementMapping, SceneTemplate } from '../../models/requirement-mapping.interface'; import { UploadSuccessModalComponent, UploadedFile } from '../../shared/components/upload-success-modal/upload-success-modal.component'; @Component({ selector: 'app-test-requirement-mapping', standalone: true, imports: [CommonModule, FormsModule, UploadSuccessModalComponent], templateUrl: './test-requirement-mapping.component.html', styleUrls: ['./test-requirement-mapping.component.scss'] }) export class TestRequirementMappingComponent implements OnInit, OnDestroy { // 测试状态 isUploading = false; isAnalyzing = false; isGeneratingMapping = false; // 上传的文件 uploadedFiles: UploadedFile[] = []; // 分析结果 analysisResult: ColorAnalysisResult | undefined = undefined; analysisError: string | null = null; // 需求映射结果 requirementMapping: RequirementMapping | null = null; mappingError: string | null = null; // 模态框状态 showUploadModal = false; // 测试步骤状态 testSteps = [ { id: 'upload', name: '图片上传', status: 'pending' as 'pending' | 'in-progress' | 'completed' | 'error' }, { id: 'analysis', name: '图片分析', status: 'pending' as 'pending' | 'in-progress' | 'completed' | 'error' }, { id: 'mapping', name: '需求映射', status: 'pending' as 'pending' | 'in-progress' | 'completed' | 'error' }, { id: 'preview', name: '氛围预览', status: 'pending' as 'pending' | 'in-progress' | 'completed' | 'error' } ]; private subscriptions: Subscription[] = []; constructor( private requirementMappingService: RequirementMappingService, private colorAnalysisService: ColorAnalysisService ) {} ngOnInit(): void { this.resetTest(); } ngOnDestroy(): void { this.subscriptions.forEach(sub => sub.unsubscribe()); // 清理对象URL this.uploadedFiles.forEach(file => { if (file.url.startsWith('blob:')) { URL.revokeObjectURL(file.url); } }); } // 重置测试 resetTest(): void { this.isUploading = false; this.isAnalyzing = false; this.isGeneratingMapping = false; this.uploadedFiles = []; this.analysisResult = undefined; this.analysisError = null; this.requirementMapping = null; this.mappingError = null; this.showUploadModal = false; this.testSteps.forEach(step => { step.status = 'pending'; }); } // 文件上传处理 onFileSelected(event: Event): void { const input = event.target as HTMLInputElement; if (!input.files || input.files.length === 0) return; this.updateStepStatus('upload', 'in-progress'); this.isUploading = true; try { const files = Array.from(input.files); this.uploadedFiles = files.map(file => ({ id: Date.now().toString() + Math.random().toString(36).substr(2, 9), name: file.name, url: URL.createObjectURL(file), size: file.size, type: 'image' as const, preview: URL.createObjectURL(file) })); // 模拟上传延迟 setTimeout(() => { this.isUploading = false; this.updateStepStatus('upload', 'completed'); this.showUploadModal = true; }, 1000); } catch (error) { console.error('文件上传失败:', error); this.isUploading = false; this.updateStepStatus('upload', 'error'); } } // 开始分析 startAnalysis(): void { if (this.uploadedFiles.length === 0) return; this.updateStepStatus('analysis', 'in-progress'); this.isAnalyzing = true; this.analysisError = null; // 使用第一个文件进行分析 const firstFile = this.uploadedFiles[0]; // 添加null检查和错误处理 if (!firstFile) { this.analysisError = '未找到有效的文件'; this.isAnalyzing = false; this.updateStepStatus('analysis', 'error'); return; } try { const analysisSubscription = this.colorAnalysisService.analyzeImage(firstFile).subscribe({ next: (result: ColorAnalysisResult) => { if (result) { this.analysisResult = result; this.isAnalyzing = false; this.updateStepStatus('analysis', 'completed'); // 自动开始需求映射 this.startRequirementMapping(); } else { this.analysisError = '分析结果为空'; this.isAnalyzing = false; this.updateStepStatus('analysis', 'error'); } }, error: (error: any) => { console.error('分析失败:', error); this.analysisError = '图片分析失败,请重试'; this.isAnalyzing = false; this.updateStepStatus('analysis', 'error'); } }); this.subscriptions.push(analysisSubscription); } catch (error) { console.error('启动分析失败:', error); this.analysisError = '启动分析失败,请重试'; this.isAnalyzing = false; this.updateStepStatus('analysis', 'error'); } } // 开始需求映射 startRequirementMapping(): void { if (!this.analysisResult) { console.warn('分析结果为空,无法开始需求映射'); return; } this.updateStepStatus('mapping', 'in-progress'); this.isGeneratingMapping = true; this.mappingError = null; try { const mappingSubscription = this.requirementMappingService.generateRequirementMapping( this.analysisResult, SceneTemplate.LIVING_ROOM_MODERN ).subscribe({ next: (mapping) => { if (mapping) { this.requirementMapping = mapping; this.isGeneratingMapping = false; this.updateStepStatus('mapping', 'completed'); this.updateStepStatus('preview', 'completed'); console.log('=== 需求映射测试完成 ==='); console.log('映射结果:', this.requirementMapping); } else { this.mappingError = '需求映射结果为空'; this.isGeneratingMapping = false; this.updateStepStatus('mapping', 'error'); } }, error: (error) => { console.error('需求映射生成失败:', error); this.mappingError = '需求映射生成失败,请重试'; this.isGeneratingMapping = false; this.updateStepStatus('mapping', 'error'); } }); this.subscriptions.push(mappingSubscription); } catch (error) { console.error('启动需求映射失败:', error); this.mappingError = '启动需求映射失败,请重试'; this.isGeneratingMapping = false; this.updateStepStatus('mapping', 'error'); } } // 更新步骤状态 private updateStepStatus(stepId: string, status: 'pending' | 'in-progress' | 'completed' | 'error'): void { const step = this.testSteps.find(s => s.id === stepId); if (step) { step.status = status; } else { console.warn(`未找到步骤: ${stepId}`); } } // 辅助方法:获取步骤图标 getStepIcon(status: string): string { switch (status) { case 'completed': return '✅'; case 'in-progress': return '⏳'; case 'error': return '❌'; default: return '⭕'; } } // 辅助方法:从HSL值生成颜色字符串 getColorFromHSL(hue: number, saturation: number, brightness: number): string { return `hsl(${hue}, ${saturation}%, ${brightness}%)`; } // 获取步骤状态类名 getStepClass(status: string): string { return `step-${status}`; } // 模态框事件处理 onCloseModal(): void { this.showUploadModal = false; } onAnalyzeColors(files: UploadedFile[]): void { this.startAnalysis(); } onViewReport(result: ColorAnalysisResult): void { console.log('查看报告:', result); } onGenerateRequirementMapping(mapping: RequirementMapping): void { console.log('需求映射生成完成:', mapping); } // 手动重试分析 retryAnalysis(): void { this.analysisError = null; this.startAnalysis(); } // 手动重试映射 retryMapping(): void { this.mappingError = null; this.startRequirementMapping(); } // 下载测试结果 downloadTestResult(): void { if (!this.requirementMapping) return; const testResult = { timestamp: new Date().toISOString(), uploadedFiles: this.uploadedFiles.map(f => ({ name: f.name, size: f.size, type: f.type })), analysisResult: this.analysisResult, requirementMapping: this.requirementMapping, testSteps: this.testSteps }; const blob = new Blob([JSON.stringify(testResult, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = `requirement-mapping-test-${Date.now()}.json`; link.click(); URL.revokeObjectURL(url); } }