| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 | <!-- 上传成功弹窗 -->@if (isVisible) {  <div class="modal-backdrop"        [@backdropAnimation]       (click)="onBackdropClick($event)">        <div class="modal-container"          [@modalAnimation]         [class.mobile]="isMobile"         [class.tablet]="isTablet"         (click)="$event.stopPropagation()">            <!-- 弹窗头部 -->      <div class="modal-header" [@fadeInOut]>        <div class="header-content">          <div class="success-icon" [@successIconAnimation]>            <svg width="32" height="32" viewBox="0 0 24 24" fill="none">              <circle cx="12" cy="12" r="10" fill="#10B981"/>              <path d="m9 12 2 2 4-4" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>            </svg>          </div>          <div class="header-text">            <h2>上传成功!</h2>            <p>已成功上传 {{ uploadedFiles.length }} 个文件</p>          </div>        </div>                <button class="close-button"                 (click)="onClose()"                [@buttonHoverAnimation]="buttonHoverState"                (mouseenter)="buttonHoverState = 'hover'"                (mouseleave)="buttonHoverState = 'normal'"                aria-label="关闭弹窗">          <svg width="24" height="24" viewBox="0 0 24 24" fill="none">            <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>          </svg>        </button>      </div>      <!-- 弹窗内容 -->      <div class="modal-content">        <!-- 已上传文件列表 -->        <div class="uploaded-files" [@fileListAnimation]="uploadedFiles.length">          <h3>已上传文件</h3>          <div class="file-list">            @for (file of uploadedFiles; track file.id) {              <div class="file-item" [@slideInOut]>                <div class="file-icon">                  @if (file.type?.startsWith('image/')) {                    <img [src]="file.preview || '/assets/images/file-image.svg'"                          [alt]="file.name"                         class="file-preview">                  } @else {                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none">                      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"                             fill="#6B7280"/>                      <polyline points="14,2 14,8 20,8" fill="#9CA3AF"/>                    </svg>                  }                </div>                <div class="file-info">                  <span class="file-name">{{ file.name }}</span>                  <span class="file-size">{{ formatFileSize(file.size || 0) }}</span>                </div>                <div class="file-status success">                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none">                    <circle cx="12" cy="12" r="10" fill="#10B981"/>                    <path d="m9 12 2 2 4-4" stroke="white" stroke-width="2" stroke-linecap="round"/>                  </svg>                </div>              </div>            }          </div>        </div>        <!-- 颜色分析功能区域 -->        @if (shouldShowColorAnalysis()) {          <div class="color-analysis-section">            <div class="section-header">              <h4>智能颜色分析</h4>              <p>基于上传的参考图片,自动提取主要色彩和材质信息</p>            </div>            <!-- 分析按钮或结果 -->            @if (!analysisResult && !isAnalyzing) {              <div class="analysis-action">                <button class="analyze-btn"                         (click)="startColorAnalysis()"                        [disabled]="isAnalyzing">                  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                    <circle cx="12" cy="12" r="3"></circle>                    <path d="M12 1v6m0 6v6m11-7h-6m-6 0H1m15.5-6.5l-4.24 4.24M7.76 16.24l-4.24 4.24m0-8.48l4.24 4.24m8.48 0l4.24-4.24"></path>                  </svg>                  开始颜色分析                </button>              </div>            }            <!-- 分析进行中 -->            @if (isAnalyzing) {              <div class="analysis-loading">                <div class="loading-spinner"></div>                <div class="loading-text">                  <h5>正在分析图片颜色...</h5>                  <p>请稍候,系统正在提取主要色彩信息</p>                </div>              </div>            }            <!-- 分析结果 -->            @if (analysisResult && !isAnalyzing) {              <div class="analysis-result">                <div class="result-header">                  <h5>颜色分析结果</h5>                  <span class="result-count">提取到 {{ analysisResult.colors.length }} 种主要颜色</span>                </div>                                <div class="color-palette">                  @for (colorInfo of analysisResult.colors; track colorInfo.hex) {                    <div class="color-item">                      <div class="color-swatch"                            [style.background-color]="colorInfo.hex"                           [title]="colorInfo.hex + ' (' + colorInfo.percentage + '%)'">                      </div>                      <div class="color-info">                        <div class="color-value">{{ colorInfo.hex }}</div>                        <div class="color-percentage">{{ colorInfo.percentage }}%</div>                      </div>                    </div>                  }                </div>                <!-- 增强分析结果 -->                @if (analysisResult.enhancedAnalysis) {                  <div class="enhanced-analysis">                    <div class="analysis-tabs">                      <button class="tab-btn"                               [class.active]="activeTab === 'color'"                              (click)="activeTab = 'color'">色彩分析</button>                      <button class="tab-btn"                               [class.active]="activeTab === 'form'"                              (click)="activeTab = 'form'">形体分析</button>                      <button class="tab-btn"                               [class.active]="activeTab === 'texture'"                              (click)="activeTab = 'texture'">质感分析</button>                      <button class="tab-btn"                               [class.active]="activeTab === 'pattern'"                              (click)="activeTab = 'pattern'">纹理分析</button>                      <button class="tab-btn"                               [class.active]="activeTab === 'lighting'"                              (click)="activeTab = 'lighting'">灯光分析</button>                      <button class="tab-btn"                               [class.active]="activeTab === 'mapping'"                              (click)="activeTab = 'mapping'">需求映射</button>                    </div>                    <div class="tab-content">                      <!-- 色彩分析标签页 -->                      @if (activeTab === 'color') {                        <div class="color-analysis-tab">                          <div class="analysis-section">                            <h6>色轮分析</h6>                            <div class="color-wheel-info">                              <div class="info-item">                                <span class="label">主色调:</span>                                <span class="value">{{ analysisResult.enhancedAnalysis.colorWheel.dominantHue }}°</span>                              </div>                              <div class="info-item">                                <span class="label">饱和度范围:</span>                                <span class="value">{{ (analysisResult.enhancedAnalysis.colorWheel.saturationRange?.min || 0) }}% - {{ (analysisResult.enhancedAnalysis.colorWheel.saturationRange?.max || 100) }}%</span>                              </div>                            </div>                          </div>                                                    <div class="analysis-section">                            <h6>色彩心理学</h6>                            <div class="psychology-info">                              <div class="mood-atmosphere">                                <span class="mood">{{ analysisResult.enhancedAnalysis.colorPsychology.mood || '无' }}</span>                                <span class="atmosphere">{{ analysisResult.enhancedAnalysis.colorPsychology.atmosphere || '无' }}</span>                              </div>                              <div class="suitable-spaces">                                @for (space of analysisResult.enhancedAnalysis.colorPsychology.suitableSpaces; track space) {                                  <span class="space-tag">{{ space }}</span>                                }                              </div>                            </div>                          </div>                        </div>                      }                      <!-- 形体分析标签页 -->                      @if (activeTab === 'form' && analysisResult.formAnalysis) {                        <div class="form-analysis-tab">                          <div class="analysis-section">                            <h6>线条分析</h6>                            <div class="form-info">                              <div class="info-item">                <span class="label">主导线条:</span>                <span class="value">{{ analysisResult.formAnalysis.lineAnalysis.dominantLineType || '无' }}</span>              </div>                              <div class="info-item">                                <span class="label">视觉流动:</span>                                <span class="value">{{ analysisResult.formAnalysis.lineAnalysis.visualFlow || '无' }}</span>                              </div>                            </div>                          </div>                                                    <div class="analysis-section">                            <h6>整体评估</h6>                            <div class="overall-info">                              <div class="metric">                                <span class="metric-label">复杂度</span>                                <div class="metric-bar">                                  <div class="metric-fill" [style.width.%]="analysisResult.formAnalysis.overallAssessment.complexity"></div>                                </div>                                <span class="metric-value">{{ analysisResult.formAnalysis.overallAssessment.complexity || 0 }}%</span>                              </div>                              <div class="metric">                                <span class="metric-label">视觉冲击</span>                                <div class="metric-bar">                                  <div class="metric-fill" [style.width.%]="analysisResult.formAnalysis.overallAssessment.visualImpact"></div>                                </div>                                <span class="metric-value">{{ analysisResult.formAnalysis.overallAssessment.visualImpact || 0 }}%</span>                              </div>                            </div>                          </div>                        </div>                      }                      <!-- 质感分析标签页 -->                      @if (activeTab === 'texture' && analysisResult.textureAnalysis) {                        <div class="texture-analysis-tab">                          <div class="analysis-section">                            <h6>表面属性</h6>                            <div class="texture-properties">                              @for (property of getTextureProperties(); track property.name) {                                <div class="property-item">                                  <span class="property-name">{{ property.name }}</span>                                  <div class="property-bar">                                    <div class="property-fill" [style.width.%]="property.value"></div>                                  </div>                                  <span class="property-value">{{ property.value }}%</span>                                </div>                              }                            </div>                          </div>                                                    <div class="analysis-section">                            <h6>材质分类</h6>                            <div class="material-tags">                              @for (material of analysisResult.textureAnalysis.materialClassification.primaryMaterials; track material; let i = $index) {                                <span class="material-tag primary">{{ material }}</span>                              }                              @for (material of analysisResult.textureAnalysis.materialClassification.secondaryMaterials; track material; let i = $index) {                                <span class="material-tag secondary">{{ material }}</span>                              }                            </div>                          </div>                        </div>                      }                      <!-- 纹理分析标签页 -->                      @if (activeTab === 'pattern' && analysisResult.patternAnalysis) {                        <div class="pattern-analysis-tab">                          <div class="analysis-section">                            <h6>图案识别</h6>                            <div class="pattern-info">                              <div class="info-item">                <span class="label">主要图案:</span>                <span class="value">{{ analysisResult.patternAnalysis.patternRecognition.primaryPatterns[0]?.type || '无' }}</span>              </div>                              <div class="info-item">                                <span class="label">复杂度:</span>                                <span class="value">{{ analysisResult.patternAnalysis.patternRecognition.patternComplexity.level || '无' }}</span>                              </div>                            </div>                          </div>                                                    <div class="analysis-section">                            <h6>视觉节奏</h6>                            <div class="rhythm-info">                              <div class="rhythm-tags">                                <span class="rhythm-tag">{{ analysisResult.patternAnalysis.visualRhythm.rhythmType.primary || '无' }}</span>                                <span class="rhythm-tag">{{ analysisResult.patternAnalysis.visualRhythm.movement.direction || '无' }}</span>                              </div>                            </div>                          </div>                        </div>                      }                      <!-- 灯光分析标签页 -->                      @if (activeTab === 'lighting' && analysisResult.lightingAnalysis) {                        <div class="lighting-analysis-tab">                          <div class="analysis-section">                            <h6>光源识别</h6>                            <div class="lighting-info">                              <div class="info-item">                <span class="label">主要光源:</span>                <span class="value">{{ analysisResult.lightingAnalysis.lightSourceIdentification.primarySources?.join(', ') || '无' }}</span>              </div>                              <div class="info-item">                                <span class="label">灯光设置:</span>                                <span class="value">{{ analysisResult.lightingAnalysis.lightSourceIdentification.lightingSetup || '无' }}</span>                              </div>                            </div>                          </div>                                                    <div class="analysis-section">                            <h6>环境分析</h6>                            <div class="ambient-info">                              <div class="info-item">                                <span class="label">环境光:</span>                                <span class="value">{{ analysisResult.lightingAnalysis.ambientAnalysis.ambientLight || '无' }}</span>                              </div>                              <div class="info-item">                                <span class="label">灯光情绪:</span>                                <span class="value">{{ analysisResult.lightingAnalysis.ambientAnalysis.lightingMood || '无' }}</span>                              </div>                            </div>                          </div>                        </div>                      }                      <!-- 需求映射标签页 -->                      @if (activeTab === 'mapping') {                        <div class="mapping-analysis-tab">                          @if (isGeneratingMapping) {                            <div class="mapping-loading">                              <div class="loading-spinner"></div>                              <div class="loading-text">                                <h6>正在生成需求映射...</h6>                                <p>基于分析结果生成场景参数和映射关系</p>                              </div>                            </div>                          } @else if (mappingError) {                            <div class="mapping-error">                              <div class="error-icon">⚠️</div>                              <div class="error-text">                                <h6>需求映射生成失败</h6>                                <p>{{ mappingError }}</p>                                <button class="retry-btn" (click)="regenerateRequirementMapping()">                                  重新生成                                </button>                              </div>                            </div>                          } @else if (requirementMapping) {                            <div class="mapping-result">                              <!-- 场景生成部分 -->                              <div class="analysis-section">                                <h6>场景生成</h6>                                <div class="scene-info">                                  <div class="info-item">                                    <span class="label">基础场景:</span>                                    <span class="value">{{ requirementMapping.sceneGeneration.baseScene }}</span>                                  </div>                                  @if (requirementMapping.sceneGeneration.atmospherePreview) {                                    <div class="atmosphere-preview">                                      <img [src]="requirementMapping.sceneGeneration.atmospherePreview"                                            alt="氛围感预览图"                                           class="preview-image">                                    </div>                                  }                                </div>                              </div>                              <!-- 参数映射部分 -->                              <div class="analysis-section">                                <h6>参数映射</h6>                                                                <!-- 颜色参数 -->                                <div class="mapping-subsection">                                  <h6>颜色映射</h6>                                  <div class="color-mappings">                                    @for (mapping of requirementMapping.parameterMapping.colorParams.primaryColors; track mapping.originalColor) {                                      <div class="color-mapping-item">                                        <div class="color-swatch" [style.background-color]="mapping.originalColor"></div>                                        <span class="mapping-arrow">→</span>                                        <span class="target-material">{{ mapping.mappedColor }}</span>                                        <span class="confidence">({{ mapping.weight }}%)</span>                                      </div>                                    }                                  </div>                                </div>                                <!-- 空间参数 -->                                <div class="mapping-subsection">                                  <h6>空间映射</h6>                                  <div class="space-info">                                    <div class="info-item">                                      <span class="label">空间类型:</span>                                      <span class="value">{{ requirementMapping.parameterMapping.spaceParams.layout?.type }}</span>                                    </div>                                    <div class="info-item">                                      <span class="label">开放程度:</span>                                      <span class="value">{{ requirementMapping.parameterMapping.spaceParams.scale?.openness }}%</span>                                    </div>                                  </div>                                </div>                                <!-- 材质参数 -->                                <div class="mapping-subsection">                                  <h6>材质映射</h6>                                  <div class="material-mappings">                                    @for (mapping of requirementMapping.parameterMapping.materialParams.surfaceMaterials; track mapping.category) {                                      <div class="material-mapping-item">                                        <span class="source-texture">{{ mapping.category }}</span>                                        <span class="mapping-arrow">→</span>                                        <span class="target-material">{{ mapping.subtype }}</span>                                        <span class="properties">{{ mapping.finish }}, {{ mapping.priority }}</span>                                      </div>                                    }                                  </div>                                </div>                              </div>                              <!-- 重新生成按钮 -->                              <div class="mapping-actions">                                <button class="regenerate-btn" (click)="regenerateRequirementMapping()">                                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                                    <polyline points="23 4 23 10 17 10"></polyline>                                    <polyline points="1 20 1 14 7 14"></polyline>                                    <path d="m3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>                                  </svg>                                  重新生成映射                                </button>                              </div>                            </div>                          } @else {                            <div class="mapping-placeholder">                              <div class="placeholder-icon">🎯</div>                              <div class="placeholder-text">                                <h6>需求映射未生成</h6>                                <p>请先完成分析,系统将自动生成需求映射</p>                              </div>                            </div>                          }                        </div>                      }                    </div>                  </div>                }                <div class="result-actions">                  <button class="view-report-btn" (click)="onViewReportClick()">                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>                      <polyline points="14,2 14,8 20,8"></polyline>                    </svg>                    查看完整报告                  </button>                </div>                <!-- 颜色描述文字区域 -->                <div class="color-description-section">                  <div class="description-header">                    <h6>颜色描述文字</h6>                    <p>适用于即梦等AI工具的颜色描述</p>                  </div>                                    <div class="description-content">                    <div class="description-text"                          [class.has-content]="generateColorDescription()"                         #descriptionText>                      {{ generateColorDescription() || '暂无颜色分析结果' }}                    </div>                                        @if (generateColorDescription()) {                      <button class="copy-description-btn"                               (click)="copyColorDescription()"                              [class.copied]="copySuccess"                              title="复制颜色描述">                        @if (copySuccess) {                          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                            <polyline points="20,6 9,17 4,12"></polyline>                          </svg>                          已复制                        } @else {                          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                            <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>                            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>                          </svg>                          复制                        }                      </button>                    }                  </div>                                    <div class="description-tips">                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                      <circle cx="12" cy="12" r="10"></circle>                      <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>                      <line x1="12" y1="17" x2="12.01" y2="17"></line>                    </svg>                    <span>复制后可直接粘贴到即梦等AI工具中,用于生成对应颜色风格的室内设计</span>                  </div>                </div>              </div>            }            <!-- 分析错误 -->            @if (analysisError) {              <div class="analysis-error">                <div class="error-icon">                  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                    <circle cx="12" cy="12" r="10"></circle>                    <line x1="15" y1="9" x2="9" y2="15"></line>                    <line x1="9" y1="9" x2="15" y2="15"></line>                  </svg>                </div>                <div class="error-text">                  <h5>分析失败</h5>                  <p>{{ analysisError }}</p>                </div>                <button class="retry-btn" (click)="startColorAnalysis()">                  重试                </button>              </div>            }          </div>        }      </div>      <!-- 弹窗底部 -->      <div class="modal-footer">        <div class="footer-actions">          <button class="secondary-btn" (click)="onClose()">            关闭          </button>          @if (shouldShowColorAnalysis() && !analysisResult) {            <button class="primary-btn"                     (click)="startColorAnalysis()"                    [disabled]="isAnalyzing">              @if (isAnalyzing) {                <div class="btn-spinner"></div>                分析中...              } @else {                开始分析              }            </button>          }        </div>      </div>    </div>  </div>}
 |