import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectionStrategy, HostListener } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ColorAnalysisService, AnalysisProgress } from '../../services/color-analysis.service'; import { Subscription } from 'rxjs'; import { modalAnimations } from './upload-success-modal.animations'; export interface UploadedFile { id: string; name: string; url: string; size?: number; type?: 'image' | 'cad' | 'text'; preview?: string; } export interface ColorAnalysisResult { colors: Array<{ hex: string; rgb: { r: number; g: number; b: number }; percentage: number }>; reportUrl?: string; mosaicUrl?: string; } @Component({ selector: 'app-upload-success-modal', standalone: true, imports: [CommonModule], templateUrl: './upload-success-modal.component.html', styleUrls: ['./upload-success-modal.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, animations: modalAnimations }) export class UploadSuccessModalComponent implements OnInit, OnDestroy { @Input() isVisible: boolean = false; @Input() uploadedFiles: UploadedFile[] = []; @Input() uploadType: 'image' | 'document' | 'mixed' = 'image'; @Input() analysisResult?: ColorAnalysisResult; @Output() closeModal = new EventEmitter(); @Output() analyzeColors = new EventEmitter(); @Output() viewReport = new EventEmitter(); // 颜色分析状态 isAnalyzing = false; analysisProgress: AnalysisProgress | null = null; analysisError: string | null = null; // 响应式状态 isMobile = false; isTablet = false; // 动画状态 animationState = 'idle'; buttonHoverState = 'normal'; private progressSubscription?: Subscription; private resizeSubscription?: Subscription; constructor(private colorAnalysisService: ColorAnalysisService) {} ngOnInit() { this.checkScreenSize(); this.setupResizeListener(); } ngOnDestroy() { this.progressSubscription?.unsubscribe(); this.resizeSubscription?.unsubscribe(); } // 响应式布局检测 @HostListener('window:resize', ['$event']) onResize(event: any) { this.checkScreenSize(); } @HostListener('document:keydown', ['$event']) onKeyDown(event: KeyboardEvent) { if (event.key === 'Escape' && this.isVisible) { this.onClose(); } } // 开始颜色分析 async startColorAnalysis() { if (this.uploadedFiles.length === 0 || this.uploadType !== 'image') { return; } this.isAnalyzing = true; this.analysisError = null; try { // 发射分析事件给父组件处理 this.analyzeColors.emit(this.uploadedFiles); // 模拟分析过程(实际应该由父组件处理并返回结果) await this.simulateAnalysis(); } catch (error) { this.analysisError = '颜色分析失败,请重试'; console.error('Color analysis error:', error); } finally { this.isAnalyzing = false; } } // 模拟分析过程 private async simulateAnalysis(): Promise { return new Promise((resolve) => { setTimeout(() => { // 模拟分析结果 this.analysisResult = { colors: [ { hex: '#8B4513', rgb: { r: 139, g: 69, b: 19 }, percentage: 35.2 }, { hex: '#A0522D', rgb: { r: 160, g: 82, b: 45 }, percentage: 27.1 }, { hex: '#D2B48C', rgb: { r: 210, g: 180, b: 140 }, percentage: 22.4 }, { hex: '#DEB887', rgb: { r: 222, g: 184, b: 135 }, percentage: 12.5 }, { hex: '#F5F5DC', rgb: { r: 245, g: 245, b: 220 }, percentage: 2.8 } ], reportUrl: '/assets/reports/color-analysis-report.html', mosaicUrl: '/assets/reports/mosaic-image.png' }; resolve(); }, 2000); }); } // 事件处理方法 onClose() { this.closeModal.emit(); } onBackdropClick(event: Event) { // 点击背景遮罩关闭弹窗 this.onClose(); } onAnalyzeColorsClick() { if (this.isAnalyzing || this.uploadedFiles.length === 0) { return; } this.animationState = 'loading'; this.analyzeColors.emit(this.uploadedFiles); } onViewReportClick() { if (this.analysisResult) { this.viewReport.emit(this.analysisResult); } } // 工具方法 shouldShowColorAnalysis(): boolean { return this.uploadType === 'image' || this.hasImageFiles(); } formatFileSize(bytes: number): string { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } getFileTypeIcon(file: UploadedFile): string { if (file.type?.startsWith('image/')) { return 'image'; } else if (file.type?.includes('pdf')) { return 'pdf'; } else if (file.type?.includes('word') || file.type?.includes('doc')) { return 'document'; } else { return 'file'; } } hasImageFiles(): boolean { return this.uploadedFiles.some(file => file.type?.startsWith('image/')); } private checkScreenSize() { const width = window.innerWidth; this.isMobile = width < 768; this.isTablet = width >= 768 && width < 1024; } private setupResizeListener() { // 可以添加更复杂的响应式逻辑 } }