requirements-optimization.md 63 KB

确认需求功能优化方案文档

📋 项目背景

当前功能概述

本文档针对需求沟通阶段确认需求功能模块进行全面分析和优化建议。该模块位于设计师项目详情页面中,是整个项目流程中的关键环节。

相关代码文件

  • 主组件src/app/shared/components/requirements-confirm-card/requirements-confirm-card.ts
  • 模板文件src/app/shared/components/requirements-confirm-card/requirements-confirm-card.html
  • 样式文件src/app/shared/components/requirements-confirm-card/requirements-confirm-card.scss
  • 父组件集成src/app/pages/designer/project-detail/project-detail.ts

当前功能架构

确认需求模块采用四标签页架构:

  1. 素材解析 - 文本、图片、CAD上传及分析
  2. 需求映射 - 基于固定场景的参数映射和氛围预览
  3. 协作验证 - 需求列表、评论、优先级管理
  4. 进度管理 - 整体进度跟踪和历史状态管理

📊 功能对比矩阵

需求文档要求 vs 当前实现对比

功能模块 需求文档要求 当前实现状态 优先级 完成度
素材分析
色彩分析 补充色轮图标,完整展示色彩信息 有基础数据,缺少可视化 🔴 高 60%
形体分析 整体形体+软装形体选择 只有分析数据,无选择功能 🔴 高 40%
质感分析 质感、材质、亮光/哑光对比 有材质分类,展示不直观 🟡 中 50%
纹理分析 图案可视化展示 只有文字标签 🟡 中 40%
灯光分析 光色、光比、光质、光占比 有光色和光质,缺光比和光占比 🔴 高 50%
完全展示所有信息 核心要求 信息折叠,展示简化 🔴 高 50%
需求映射
功能定位 隐藏功能,后台自动生成 独立标签页,用户可见 🟡 中 需调整
协作验证
五维度验证 色彩、形体、质感、纹理、灯光分类 通用需求列表 🔴 高 20%
素材关联 关联参考图、CAD、文字说明 无关联机制 🔴 高 0%
选择和标注 交互式标注工具 无标注功能 🔴 高 0%
区域细分 支持不同区域(客厅、婴儿房等) 只有整体方案 🔴 高 0%
分工人员 不同区域分配不同人员 只有角色标识 🟡 中 10%

🎯 详细优化点清单

A. 素材分析标签页优化

A1. 色彩分析增强 🔴 高优先级

当前问题

  • 只显示简单的SVG图标
  • 色彩数据展示不够直观
  • 缺少交互式色轮可视化

优化方案

1. 交互式色轮可视化组件

// 新建组件:src/app/shared/components/color-wheel-visualizer/
interface ColorWheelConfig {
  colors: Array<{
    hue: number;        // 色调角度 0-360
    saturation: number; // 饱和度 0-100
    brightness: number; // 亮度 0-100
    percentage: number; // 占比
    hex: string;
  }>;
  interactive: boolean; // 是否可交互
}

功能特性:

  • SVG绘制的色轮,显示360度色相环
  • 在色轮上标注主要颜色的位置
  • 鼠标悬停显示详细信息(RGB、HEX、HSB值)
  • 显示色彩分布饼图
  • 色彩和谐度可视化(单色、类似色、互补色等)

2. 色彩详情卡片

<div class="color-analysis-detail">
  <div class="color-wheel-container">
    <app-color-wheel-visualizer 
      [colors]="material.analysis.enhancedColorAnalysis.colorWheel.colorDistribution"
      [interactive]="true">
    </app-color-wheel-visualizer>
  </div>
  
  <div class="color-info-grid">
    <!-- 主色调信息 -->
    <div class="color-metric">
      <span class="label">主色调</span>
      <div class="hue-indicator" [style.background]="getHueColor()"></div>
      <span class="value">{{ primaryHue }}°</span>
    </div>
    
    <!-- 饱和度 -->
    <div class="color-metric">
      <span class="label">饱和度</span>
      <div class="saturation-bar">
        <div class="fill" [style.width.%]="saturation"></div>
      </div>
      <span class="value">{{ saturation }}%</span>
    </div>
    
    <!-- 色温 -->
    <div class="color-metric">
      <span class="label">色温</span>
      <div class="temperature-indicator" [class]="temperatureClass"></div>
      <span class="value">{{ temperature }}K ({{ temperatureDesc }})</span>
    </div>
    
    <!-- 色彩心理学 -->
    <div class="color-psychology">
      <h6>色彩心理学</h6>
      <div class="mood-tags">
        <span class="mood-tag primary">{{ primaryMood }}</span>
        <span class="atmosphere-tag">{{ atmosphere }}</span>
      </div>
      <ul class="effects-list">
        <li *ngFor="let effect of psychologicalEffects">{{ effect }}</li>
      </ul>
    </div>
  </div>
</div>

3. 技术实施细节

  • 使用D3.js或纯SVG实现色轮
  • 响应式设计,适配不同屏幕尺寸
  • 动画过渡效果
  • 支持导出色板

A2. 形体分析补充 🔴 高优先级

当前问题

  • 只展示形体复杂度和视觉冲击的数值
  • 缺少软装形体的分类和选择功能
  • 无法针对特定形体进行标注

优化方案

1. 形体分类展示

interface FormCategory {
  overall: {
    lineType: 'straight' | 'curved' | 'mixed';  // 直线/曲线/混合
    complexity: number;                          // 复杂度 0-100
    symmetry: 'symmetric' | 'asymmetric';       // 对称/不对称
  };
  furniture: {
    dominant: string[];      // 主要家具形体
    style: string;          // 风格(简约、古典、现代等)
    proportion: number;     // 占比
  };
}

2. 软装形体选择器

<div class="form-analysis-section">
  <h6>形体分析</h6>
  
  <!-- 整体形体 -->
  <div class="overall-form">
    <div class="form-type-selector">
      <label>线条类型:</label>
      <div class="type-options">
        <button class="type-btn" 
                [class.active]="formType === 'straight'"
                (click)="selectFormType('straight')">
          <svg><!-- 直线图标 --></svg>
          直线条
        </button>
        <button class="type-btn" 
                [class.active]="formType === 'curved'"
                (click)="selectFormType('curved')">
          <svg><!-- 曲线图标 --></svg>
          曲线条
        </button>
        <button class="type-btn" 
                [class.active]="formType === 'mixed'"
                (click)="selectFormType('mixed')">
          <svg><!-- 混合图标 --></svg>
          混合型
        </button>
      </div>
    </div>
    
    <!-- 对称性 -->
    <div class="symmetry-indicator">
      <span class="label">对称性:</span>
      <div class="symmetry-visual">
        <svg><!-- 对称性可视化图标 --></svg>
      </div>
      <span class="value">{{ symmetryType }}</span>
    </div>
  </div>
  
  <!-- 软装形体选择 -->
  <div class="furniture-form-selector">
    <h6>软装形体选择</h6>
    <div class="furniture-grid">
      <div class="furniture-item" 
           *ngFor="let item of furnitureItems"
           [class.selected]="item.selected"
           (click)="toggleFurniture(item)">
        <img [src]="item.preview" [alt]="item.name">
        <span class="name">{{ item.name }}</span>
        <span class="form-tag">{{ item.formType }}</span>
      </div>
    </div>
  </div>
  
  <!-- 形体比例分析 -->
  <div class="proportion-analysis">
    <h6>形体比例分析</h6>
    <div class="proportion-chart">
      <!-- 使用ECharts绘制比例图 -->
    </div>
  </div>
</div>

3. 数据模型扩展

interface FurnitureFormItem {
  id: string;
  name: string;
  category: 'sofa' | 'table' | 'chair' | 'cabinet' | 'bed' | 'decoration';
  formType: 'geometric' | 'organic' | 'linear' | 'curved';
  preview: string;
  selected: boolean;
  dominance: number; // 视觉主导性
}

A3. 质感分析优化 🟡 中优先级

当前问题

  • 只显示材质类别和粗糙度等级文字
  • 亮光/哑光对比不明显
  • 缺少质感的视觉化展示

优化方案

1. 亮光/哑光对比卡片

<div class="texture-analysis-section">
  <h6>质感分析</h6>
  
  <!-- 光泽度对比 -->
  <div class="glossiness-comparison">
    <div class="gloss-card matte" [class.active]="glossType === 'matte'">
      <div class="gloss-preview matte-texture">
        <span class="label">哑光</span>
        <div class="gloss-level">{{ matteLevel }}/10</div>
      </div>
      <div class="gloss-properties">
        <span>柔和 · 低反射 · 温暖</span>
      </div>
    </div>
    
    <div class="gloss-card glossy" [class.active]="glossType === 'glossy'">
      <div class="gloss-preview glossy-texture">
        <span class="label">亮光</span>
        <div class="gloss-level">{{ glossyLevel }}/10</div>
      </div>
      <div class="gloss-properties">
        <span>明亮 · 高反射 · 现代</span>
      </div>
    </div>
  </div>
  
  <!-- 材质属性详情 -->
  <div class="material-properties">
    <div class="property-row">
      <span class="label">粗糙度</span>
      <div class="property-bar">
        <div class="fill roughness" [style.width.%]="roughness"></div>
        <span class="value">{{ roughnessLevel }}</span>
      </div>
    </div>
    
    <div class="property-row">
      <span class="label">反射率</span>
      <div class="property-bar">
        <div class="fill reflectivity" [style.width.%]="reflectivity"></div>
        <span class="value">{{ reflectivity }}%</span>
      </div>
    </div>
    
    <div class="property-row">
      <span class="label">质感层次</span>
      <div class="texture-layers">
        <span class="layer" *ngFor="let layer of textureLayers">{{ layer }}</span>
      </div>
    </div>
  </div>
  
  <!-- 材质分类 -->
  <div class="material-classification">
    <h6>材质类型</h6>
    <div class="material-tags">
      <span class="material-tag primary">{{ primaryMaterial }}</span>
      <span class="material-tag" *ngFor="let mat of secondaryMaterials">
        {{ mat.name }} ({{ mat.percentage }}%)
      </span>
    </div>
  </div>
</div>

2. 质感预览组件

使用3D渲染或高质量图片展示不同质感效果:

  • 木质(哑光/亮光)
  • 金属(拉丝/抛光)
  • 织物(粗糙/光滑)
  • 石材(天然/磨光)

A4. 纹理分析增强 🟡 中优先级

当前问题

  • 只有纹理类型的文字标签
  • 缺少图案的可视化展示
  • 无法直观了解纹理重复规律

优化方案

1. 纹理图案可视化

<div class="pattern-analysis-section">
  <h6>纹理分析</h6>
  
  <!-- 图案预览 -->
  <div class="pattern-preview-grid">
    <div class="pattern-item" *ngFor="let pattern of recognizedPatterns">
      <div class="pattern-visual">
        <!-- 截取参考图中的纹理区域显示 -->
        <img [src]="pattern.sampleImage" [alt]="pattern.type">
        <div class="pattern-overlay">
          <span class="pattern-type">{{ pattern.type }}</span>
          <span class="coverage">{{ pattern.coverage }}%</span>
        </div>
      </div>
      <div class="pattern-info">
        <span class="complexity">复杂度: {{ pattern.complexity }}</span>
        <span class="scale">尺度: {{ pattern.scale }}</span>
      </div>
    </div>
  </div>
  
  <!-- 重复规律分析 -->
  <div class="repetition-analysis">
    <h6>重复规律</h6>
    <div class="repetition-visual">
      <svg>
        <!-- 绘制网格或重复单元 -->
      </svg>
    </div>
    <div class="repetition-info">
      <div class="info-row">
        <span class="label">重复类型:</span>
        <span class="value">{{ repetitionType }}</span>
      </div>
      <div class="info-row">
        <span class="label">间距:</span>
        <span class="value">横向 {{ spacingH }}mm · 纵向 {{ spacingV }}mm</span>
      </div>
      <div class="info-row">
        <span class="label">对称性:</span>
        <span class="value">{{ symmetryType }} (强度 {{ symmetryStrength }}%)</span>
      </div>
    </div>
  </div>
  
  <!-- 纹理族 -->
  <div class="texture-family">
    <h6>纹理族系</h6>
    <div class="family-tags">
      <span class="family-tag primary">{{ primaryFamily }}</span>
      <span class="family-tag">{{ subcategory }}</span>
    </div>
    <div class="suggested-materials">
      <span class="label">建议材质:</span>
      <span class="material" *ngFor="let mat of suggestedMaterials">{{ mat }}</span>
    </div>
  </div>
</div>

2. 技术实施

  • 使用Canvas API提取纹理样本
  • 傅里叶变换分析重复模式
  • 提供纹理缩放预览
  • 支持纹理导出

A5. 灯光分析补充 🔴 高优先级

当前问题

  • 只有光源类型、亮度、情绪
  • 缺少光比数据
  • 缺少光占比数据
  • 光质展示不够直观

优化方案

1. 完整的灯光分析面板

interface CompleteLightingAnalysis {
  // 现有数据
  lightSource: {
    type: string;
    intensity: number;
    mood: string;
  };
  
  // 新增:光比
  lightingRatio: {
    keyToFill: number;      // 主光与补光比例 (如 3:1)
    contrast: number;       // 明暗对比度
    description: string;    // 高反差/低反差/中等
  };
  
  // 新增:光占比
  lightDistribution: {
    natural: number;        // 自然光占比 %
    artificial: number;     // 人工光占比 %
    ambient: number;        // 环境光占比 %
    direct: number;         // 直射光占比 %
    indirect: number;       // 间接光占比 %
  };
  
  // 光质
  lightQuality: {
    softness: number;       // 柔和度
    diffusion: number;      // 漫射度
    directionality: number; // 方向性
  };
}

2. 灯光分析UI

<div class="lighting-analysis-section">
  <h6>灯光分析</h6>
  
  <!-- 光源识别 -->
  <div class="light-sources">
    <div class="source-item" *ngFor="let source of lightSources">
      <div class="source-icon" [class]="source.type">
        <svg><!-- 光源图标 --></svg>
      </div>
      <div class="source-info">
        <span class="type">{{ source.subtype }}</span>
        <span class="intensity">强度 {{ source.intensity }}%</span>
      </div>
    </div>
  </div>
  
  <!-- 光比分析 NEW -->
  <div class="lighting-ratio">
    <h6>光比分析</h6>
    <div class="ratio-visual">
      <div class="ratio-bars">
        <div class="key-light-bar" [style.height.%]="keyLightRatio">
          <span>主光</span>
          <span class="value">{{ keyLightRatio }}%</span>
        </div>
        <div class="fill-light-bar" [style.height.%]="fillLightRatio">
          <span>补光</span>
          <span class="value">{{ fillLightRatio }}%</span>
        </div>
      </div>
      <div class="ratio-description">
        <span class="ratio-value">{{ keyToFillRatio }}</span>
        <span class="contrast-level">{{ contrastDescription }}</span>
      </div>
    </div>
  </div>
  
  <!-- 光占比饼图 NEW -->
  <div class="light-distribution">
    <h6>光占比</h6>
    <div class="distribution-chart">
      <!-- 使用ECharts绘制饼图 -->
      <canvas id="lightDistributionChart"></canvas>
    </div>
    <div class="distribution-legend">
      <div class="legend-item">
        <span class="color natural"></span>
        <span class="label">自然光</span>
        <span class="value">{{ naturalLight }}%</span>
      </div>
      <div class="legend-item">
        <span class="color artificial"></span>
        <span class="label">人工光</span>
        <span class="value">{{ artificialLight }}%</span>
      </div>
      <div class="legend-item">
        <span class="color ambient"></span>
        <span class="label">环境光</span>
        <span class="value">{{ ambientLight }}%</span>
      </div>
    </div>
  </div>
  
  <!-- 光质分析 -->
  <div class="light-quality">
    <h6>光质</h6>
    <div class="quality-metrics">
      <div class="metric-item">
        <span class="label">柔和度</span>
        <div class="metric-bar">
          <div class="fill" [style.width.%]="softness"></div>
        </div>
        <span class="value">{{ softness }}%</span>
      </div>
      <div class="metric-item">
        <span class="label">漫射度</span>
        <div class="metric-bar">
          <div class="fill" [style.width.%]="diffusion"></div>
        </div>
        <span class="value">{{ diffusion }}%</span>
      </div>
      <div class="metric-item">
        <span class="label">方向性</span>
        <div class="metric-bar">
          <div class="fill" [style.width.%]="directionality"></div>
        </div>
        <span class="value">{{ directionality }}%</span>
      </div>
    </div>
  </div>
  
  <!-- 色温与情绪 -->
  <div class="color-temperature-mood">
    <div class="temperature">
      <span class="label">色温</span>
      <div class="temp-bar" [style.background]="tempGradient"></div>
      <span class="value">{{ colorTemp }}K</span>
    </div>
    <div class="mood">
      <span class="label">灯光情绪</span>
      <span class="mood-tag">{{ lightingMood }}</span>
    </div>
  </div>
</div>

3. 服务层扩展

修改 src/app/shared/services/lighting-analysis.service.ts

// 新增光比计算方法
calculateLightingRatio(image: File): Observable<LightingRatioResult> {
  // 分析图像的亮度分布
  // 识别主光源和补光源
  // 计算光比
}

// 新增光占比计算方法
calculateLightDistribution(lightingData: any): LightDistribution {
  // 根据光源识别结果计算各类光源占比
}

A6. 全展示模式 🔴 高优先级

当前问题

  • 分析结果折叠显示,用户需要点击展开
  • 无法一次性查看所有素材的完整分析
  • 核心要求是"完全展示所有采集的参考信息"

优化方案

1. 展开/折叠控制

<div class="materials-list">
  <div class="list-header">
    <h5>已上传素材</h5>
    <div class="view-controls">
      <button class="btn-ghost" 
              [class.active]="viewMode === 'compact'"
              (click)="setViewMode('compact')">
        精简视图
      </button>
      <button class="btn-ghost" 
              [class.active]="viewMode === 'expanded'"
              (click)="setViewMode('expanded')">
        完整展示
      </button>
      <button class="btn-ghost" (click)="expandAll()">全部展开</button>
      <button class="btn-ghost" (click)="collapseAll()">全部折叠</button>
    </div>
  </div>
  
  <div class="material-cards" [class]="viewMode">
    <!-- 素材卡片 -->
  </div>
</div>

2. 完整展示模式布局

.material-cards.expanded {
  .material-card {
    .analysis-section {
      display: block !important; // 强制展开所有分析部分
      
      .color-wheel-visualizer,
      .form-analysis-section,
      .texture-analysis-section,
      .pattern-analysis-section,
      .lighting-analysis-section {
        max-height: none;
        overflow: visible;
      }
    }
  }
}

3. 打印/导出功能

// 新增导出分析报告功能
exportAnalysisReport(materialId: string, format: 'pdf' | 'excel' | 'json') {
  const material = this.materials.find(m => m.id === materialId);
  // 生成完整的分析报告
}

// 批量导出所有素材
exportAllMaterials() {
  // 导出所有素材的完整分析数据
}

B. 需求映射调整 🟡 中优先级

当前问题

  • 需求映射作为独立标签页展示给用户
  • 文档要求:应该是隐藏功能,在后台自动生成

优化方案

1. 移除"需求映射"标签页

修改 requirements-confirm-card.html

<!-- 移除需求映射标签按钮 -->
<div class="tab-navigation">
  <button class="tab-button" [class.active]="activeTab === 'materials'">素材解析</button>
  <!-- <button class="tab-button" [class.active]="activeTab === 'mapping'">需求映射</button> --> 
  <!-- 移除此标签 -->
  <button class="tab-button" [class.active]="activeTab === 'collaboration'">协作验证</button>
  <button class="tab-button" [class.active]="activeTab === 'progress'">进度管理</button>
</div>

2. 自动触发映射机制

// 在素材分析完成后自动触发
private onMaterialAnalysisComplete(material: MaterialFile): void {
  // 检查是否所有素材都已分析完成
  const allAnalyzed = this.materials.every(m => m.analysis);
  
  if (allAnalyzed) {
    console.log('所有素材分析完成,自动触发需求映射');
    this.triggerBackgroundMapping();
  }
}

// 后台映射生成
private triggerBackgroundMapping(): void {
  this.isGeneratingMapping = true;
  
  // 收集所有分析结果
  const analysisResults = this.materials
    .filter(m => m.type === 'image')
    .map(m => this.convertToColorAnalysisResult(m));
  
  // 自动生成需求映射(不显示给用户)
  this.requirementMappingService.generateRequirementMapping(
    this.mergeAnalysisResults(analysisResults),
    SceneTemplate.LIVING_ROOM_MODERN
  ).subscribe({
    next: (mapping) => {
      this.requirementMapping = mapping;
      this.isGeneratingMapping = false;
      
      // 静默保存,不弹窗提示
      console.log('需求映射已自动生成:', mapping);
      
      // 发送映射数据到父组件(用于方案确认阶段展示)
      this.emitMappingDataUpdate();
    },
    error: (error) => {
      console.error('自动映射生成失败:', error);
      this.isGeneratingMapping = false;
    }
  });
}

3. 保留数据接口

// 保留映射数据的访问接口,供其他模块使用
public getMappingData(): RequirementMapping | null {
  return this.requirementMapping;
}

// 提供重新生成映射的方法(调试用)
public regenerateMapping(): void {
  this.triggerBackgroundMapping();
}

4. 在开发模式下保留可见性(可选)

// 环境配置
showMappingTab = environment.production ? false : true;
<button class="tab-button" 
        *ngIf="showMappingTab"
        [class.active]="activeTab === 'mapping'">
  需求映射 (调试)
</button>

C. 协作验证重构 🔴 高优先级(核心)

这是最重要的优化模块,需要完全重构当前的协作验证功能。

C1. 五维验证模块设计

当前问题

  • 只有通用的需求列表(色彩氛围、空间布局、材质选择)
  • 没有按照五个维度(色彩、形体、质感、纹理、灯光)分类
  • 无法针对特定维度进行深度验证

优化方案

1. 数据模型重构

// 新建接口:src/app/models/collaboration-verification.interface.ts

export interface DimensionVerification {
  id: string;
  dimension: 'color' | 'form' | 'texture' | 'pattern' | 'lighting';
  dimensionName: string;
  status: 'pending' | 'in-review' | 'confirmed' | 'rejected';
  
  // 关联的素材
  linkedMaterials: LinkedMaterial[];
  
  // 验证项
  verificationItems: VerificationItem[];
  
  // 标注
  annotations: Annotation[];
  
  // 协作信息
  assignedTo?: string;
  comments: Comment[];
  
  // 区域(如果是区域细分)
  areaId?: string;
  
  lastUpdated: Date;
}

export interface LinkedMaterial {
  materialId: string;
  materialType: 'image' | 'cad' | 'text';
  materialName: string;
  relevance: number; // 相关度 0-100
  highlightAreas?: Array<{x: number; y: number; width: number; height: number}>;
}

export interface VerificationItem {
  id: string;
  title: string;
  description: string;
  status: 'pending' | 'confirmed' | 'rejected';
  priority: 'high' | 'medium' | 'low';
  tags: string[];
}

export interface Annotation {
  id: string;
  type: 'text' | 'arrow' | 'highlight' | 'circle' | 'rectangle';
  content?: string;
  position: {x: number; y: number};
  size?: {width: number; height: number};
  color: string;
  author: string;
  timestamp: Date;
  linkedMaterialId: string;
}

2. 五维验证UI布局

<div class="collaboration-section-redesign">
  <div class="section-header">
    <h5>协作验证</h5>
    <div class="dimension-selector">
      <button class="dimension-tab" 
              *ngFor="let dim of dimensions"
              [class.active]="activeDimension === dim.key"
              (click)="selectDimension(dim.key)">
        <svg [innerHTML]="dim.icon"></svg>
        <span>{{ dim.name }}</span>
        <span class="status-badge" [class]="getDimensionStatus(dim.key)">
          {{ getDimensionStatusText(dim.key) }}
        </span>
      </button>
    </div>
  </div>
  
  <!-- 当前维度的验证内容 -->
  <div class="dimension-content" [ngSwitch]="activeDimension">
    
    <!-- 色彩验证 -->
    <div *ngSwitchCase="'color'" class="color-verification">
      <app-dimension-verification 
        [dimension]="'color'"
        [materials]="getColorRelatedMaterials()"
        [verificationData]="colorVerificationData"
        (materialLinked)="onMaterialLinked($event)"
        (annotationAdded)="onAnnotationAdded($event)"
        (statusChanged)="onVerificationStatusChanged($event)">
      </app-dimension-verification>
    </div>
    
    <!-- 形体验证 -->
    <div *ngSwitchCase="'form'" class="form-verification">
      <app-dimension-verification 
        [dimension]="'form'"
        [materials]="getFormRelatedMaterials()"
        [verificationData]="formVerificationData">
      </app-dimension-verification>
    </div>
    
    <!-- 质感验证 -->
    <div *ngSwitchCase="'texture'" class="texture-verification">
      <app-dimension-verification 
        [dimension]="'texture'"
        [materials]="getTextureRelatedMaterials()"
        [verificationData]="textureVerificationData">
      </app-dimension-verification>
    </div>
    
    <!-- 纹理验证 -->
    <div *ngSwitchCase="'pattern'" class="pattern-verification">
      <app-dimension-verification 
        [dimension]="'pattern'"
        [materials]="getPatternRelatedMaterials()"
        [verificationData]="patternVerificationData">
      </app-dimension-verification>
    </div>
    
    <!-- 灯光验证 -->
    <div *ngSwitchCase="'lighting'" class="lighting-verification">
      <app-dimension-verification 
        [dimension]="'lighting'"
        [materials]="getLightingRelatedMaterials()"
        [verificationData]="lightingVerificationData">
      </app-dimension-verification>
    </div>
  </div>
</div>

3. 新建维度验证组件

创建 src/app/shared/components/dimension-verification/

@Component({
  selector: 'app-dimension-verification',
  templateUrl: './dimension-verification.component.html',
  styleUrls: ['./dimension-verification.component.scss']
})
export class DimensionVerificationComponent implements OnInit {
  @Input() dimension!: 'color' | 'form' | 'texture' | 'pattern' | 'lighting';
  @Input() materials: MaterialFile[] = [];
  @Input() verificationData?: DimensionVerification;
  
  @Output() materialLinked = new EventEmitter<LinkedMaterial>();
  @Output() annotationAdded = new EventEmitter<Annotation>();
  @Output() statusChanged = new EventEmitter<{dimension: string; status: string}>();
  
  // 组件逻辑...
}

C2. 素材关联系统

功能设计

1. 拖拽关联

<div class="material-linking-panel">
  <div class="source-materials">
    <h6>素材库</h6>
    <div class="material-list" 
         cdkDropList
         #materialList="cdkDropList"
         [cdkDropListData]="availableMaterials"
         [cdkDropListConnectedTo]="[linkedList]">
      
      <div class="material-item" 
           *ngFor="let material of availableMaterials"
           cdkDrag>
        <img [src]="material.url" [alt]="material.name">
        <span>{{ material.name }}</span>
      </div>
    </div>
  </div>
  
  <div class="linked-materials">
    <h6>已关联素材 - {{ dimensionName }}</h6>
    <div class="linked-list"
         cdkDropList
         #linkedList="cdkDropList"
         [cdkDropListData]="linkedMaterials"
         [cdkDropListConnectedTo]="[materialList]"
         (cdkDropListDropped)="onMaterialDropped($event)">
      
      <div class="linked-item" 
           *ngFor="let linked of linkedMaterials"
           cdkDrag>
        <img [src]="linked.materialUrl" [alt]="linked.materialName">
        <div class="linked-info">
          <span class="name">{{ linked.materialName }}</span>
          <span class="relevance">相关度: {{ linked.relevance }}%</span>
        </div>
        <button class="btn-remove" (click)="unlinkMaterial(linked.id)">
          <svg><!-- 删除图标 --></svg>
        </button>
      </div>
    </div>
  </div>
</div>

2. 下拉选择关联

<div class="material-selector">
  <label>关联参考图:</label>
  <select (change)="linkMaterial($event.target.value)">
    <option value="">-- 选择素材 --</option>
    <option *ngFor="let material of availableMaterials" 
            [value]="material.id">
      {{ material.name }}
    </option>
  </select>
</div>

3. 关联逻辑实现

onMaterialDropped(event: CdkDragDrop<MaterialFile[]>) {
  if (event.previousContainer === event.container) {
    moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
  } else {
    transferArrayItem(
      event.previousContainer.data,
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
    
    // 创建关联
    const material = event.container.data[event.currentIndex];
    this.createMaterialLink(material);
  }
}

private createMaterialLink(material: MaterialFile): void {
  const linked: LinkedMaterial = {
    materialId: material.id,
    materialType: material.type,
    materialName: material.name,
    relevance: this.calculateRelevance(material), // 自动计算相关度
    highlightAreas: []
  };
  
  this.materialLinked.emit(linked);
}

// 计算素材与当前维度的相关度
private calculateRelevance(material: MaterialFile): number {
  // 根据维度和素材分析结果计算相关度
  switch(this.dimension) {
    case 'color':
      return material.analysis?.enhancedColorAnalysis ? 90 : 50;
    case 'form':
      return material.analysis?.formAnalysis ? 85 : 40;
    case 'texture':
      return material.analysis?.textureAnalysis ? 88 : 45;
    case 'pattern':
      return material.analysis?.patternAnalysis ? 82 : 35;
    case 'lighting':
      return material.analysis?.lightingAnalysis ? 92 : 50;
    default:
      return 50;
  }
}

C3. 标注工具集成

功能设计

1. 标注工具栏

<div class="annotation-toolbar">
  <button class="tool-btn" 
          [class.active]="activeTool === 'text'"
          (click)="selectTool('text')">
    <svg><!-- 文本图标 --></svg>
    文字
  </button>
  
  <button class="tool-btn" 
          [class.active]="activeTool === 'arrow'"
          (click)="selectTool('arrow')">
    <svg><!-- 箭头图标 --></svg>
    箭头
  </button>
  
  <button class="tool-btn" 
          [class.active]="activeTool === 'highlight'"
          (click)="selectTool('highlight')">
    <svg><!-- 高亮图标 --></svg>
    高亮
  </button>
  
  <button class="tool-btn" 
          [class.active]="activeTool === 'circle'"
          (click)="selectTool('circle')">
    <svg><!-- 圆圈图标 --></svg>
    圆圈
  </button>
  
  <button class="tool-btn" 
          [class.active]="activeTool === 'rectangle'"
          (click)="selectTool('rectangle')">
    <svg><!-- 矩形图标 --></svg>
    矩形
  </button>
  
  <div class="color-picker">
    <input type="color" 
           [(ngModel)]="annotationColor"
           title="标注颜色">
  </div>
  
  <button class="tool-btn" (click)="clearAnnotations()">
    <svg><!-- 清除图标 --></svg>
    清除全部
  </button>
</div>

2. 标注画布

<div class="annotation-canvas-container">
  <div class="canvas-wrapper">
    <!-- 底层:原始图片 -->
    <img [src]="selectedMaterial.url" 
         class="base-image"
         #baseImage>
    
    <!-- 中层:SVG标注层 -->
    <svg class="annotation-layer"
         [attr.width]="canvasWidth"
         [attr.height]="canvasHeight"
         (mousedown)="startAnnotation($event)"
         (mousemove)="continueAnnotation($event)"
         (mouseup)="finishAnnotation($event)">
      
      <!-- 已有标注 -->
      <g *ngFor="let annotation of annotations" 
         [attr.data-id]="annotation.id"
         class="annotation-item"
         (click)="selectAnnotation(annotation)">
        
        <!-- 文字标注 -->
        <text *ngIf="annotation.type === 'text'"
              [attr.x]="annotation.position.x"
              [attr.y]="annotation.position.y"
              [attr.fill]="annotation.color">
          {{ annotation.content }}
        </text>
        
        <!-- 箭头标注 -->
        <line *ngIf="annotation.type === 'arrow'"
              [attr.x1]="annotation.start.x"
              [attr.y1]="annotation.start.y"
              [attr.x2]="annotation.end.x"
              [attr.y2]="annotation.end.y"
              [attr.stroke]="annotation.color"
              stroke-width="2"
              marker-end="url(#arrowhead)">
        </line>
        
        <!-- 高亮标注 -->
        <rect *ngIf="annotation.type === 'highlight'"
              [attr.x]="annotation.position.x"
              [attr.y]="annotation.position.y"
              [attr.width]="annotation.size.width"
              [attr.height]="annotation.size.height"
              [attr.fill]="annotation.color"
              opacity="0.3">
        </rect>
        
        <!-- 圆圈标注 -->
        <circle *ngIf="annotation.type === 'circle'"
                [attr.cx]="annotation.position.x"
                [attr.cy]="annotation.position.y"
                [attr.r]="annotation.radius"
                [attr.stroke]="annotation.color"
                stroke-width="2"
                fill="none">
        </circle>
        
        <!-- 矩形标注 -->
        <rect *ngIf="annotation.type === 'rectangle'"
              [attr.x]="annotation.position.x"
              [attr.y]="annotation.position.y"
              [attr.width]="annotation.size.width"
              [attr.height]="annotation.size.height"
              [attr.stroke]="annotation.color"
              stroke-width="2"
              fill="none">
        </rect>
      </g>
      
      <!-- 箭头标记定义 -->
      <defs>
        <marker id="arrowhead" markerWidth="10" markerHeight="10" 
                refX="5" refY="5" orient="auto">
          <polygon points="0 0, 10 5, 0 10" [attr.fill]="annotationColor" />
        </marker>
      </defs>
    </svg>
  </div>
  
  <!-- 标注列表 -->
  <div class="annotation-list">
    <h6>标注列表</h6>
    <div class="annotation-item-list">
      <div class="list-item" 
           *ngFor="let annotation of annotations"
           [class.selected]="selectedAnnotation?.id === annotation.id"
           (click)="selectAnnotation(annotation)">
        <span class="type-icon">{{ getAnnotationIcon(annotation.type) }}</span>
        <span class="content">{{ annotation.content || annotation.type }}</span>
        <span class="author">{{ annotation.author }}</span>
        <button class="btn-delete" (click)="deleteAnnotation(annotation.id)">
          <svg><!-- 删除图标 --></svg>
        </button>
      </div>
    </div>
  </div>
</div>

3. 标注逻辑实现

export class AnnotationToolComponent {
  activeTool: 'text' | 'arrow' | 'highlight' | 'circle' | 'rectangle' | null = null;
  annotationColor = '#FF0000';
  annotations: Annotation[] = [];
  isDrawing = false;
  currentAnnotation: Partial<Annotation> | null = null;
  
  startAnnotation(event: MouseEvent): void {
    if (!this.activeTool) return;
    
    this.isDrawing = true;
    const rect = (event.target as HTMLElement).getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    
    this.currentAnnotation = {
      id: this.generateId(),
      type: this.activeTool,
      position: { x, y },
      color: this.annotationColor,
      author: this.getCurrentUser(),
      timestamp: new Date()
    };
  }
  
  continueAnnotation(event: MouseEvent): void {
    if (!this.isDrawing || !this.currentAnnotation) return;
    
    const rect = (event.target as HTMLElement).getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    
    // 根据工具类型更新标注
    if (this.activeTool === 'arrow') {
      this.currentAnnotation.end = { x, y };
    } else if (['highlight', 'rectangle'].includes(this.activeTool!)) {
      this.currentAnnotation.size = {
        width: x - this.currentAnnotation.position!.x,
        height: y - this.currentAnnotation.position!.y
      };
    } else if (this.activeTool === 'circle') {
      const dx = x - this.currentAnnotation.position!.x;
      const dy = y - this.currentAnnotation.position!.y;
      this.currentAnnotation.radius = Math.sqrt(dx * dx + dy * dy);
    }
  }
  
  finishAnnotation(event: MouseEvent): void {
    if (!this.isDrawing || !this.currentAnnotation) return;
    
    this.isDrawing = false;
    
    // 如果是文字工具,弹出输入框
    if (this.activeTool === 'text') {
      const text = prompt('请输入标注内容:');
      if (text) {
        this.currentAnnotation.content = text;
        this.annotations.push(this.currentAnnotation as Annotation);
        this.annotationAdded.emit(this.currentAnnotation as Annotation);
      }
    } else {
      this.annotations.push(this.currentAnnotation as Annotation);
      this.annotationAdded.emit(this.currentAnnotation as Annotation);
    }
    
    this.currentAnnotation = null;
  }
  
  deleteAnnotation(id: string): void {
    const index = this.annotations.findIndex(a => a.id === id);
    if (index !== -1) {
      this.annotations.splice(index, 1);
    }
  }
  
  clearAnnotations(): void {
    if (confirm('确定清除所有标注吗?')) {
      this.annotations = [];
    }
  }
}

C4. 区域细分管理

功能设计

1. 区域管理面板

<div class="area-management-panel">
  <div class="panel-header">
    <h5>区域细分管理</h5>
    <button class="btn-primary" (click)="addNewArea()">
      <svg><!-- 添加图标 --></svg>
      新增区域
    </button>
  </div>
  
  <!-- 整体方案 -->
  <div class="overall-plan" 
       [class.active]="selectedArea === null"
       (click)="selectArea(null)">
    <div class="area-header">
      <svg><!-- 整体图标 --></svg>
      <h6>整体方案</h6>
      <span class="area-status" [class]="overallStatus">{{ getStatusText(overallStatus) }}</span>
    </div>
    <div class="area-summary">
      <span>默认统一风格设计</span>
    </div>
  </div>
  
  <!-- 细分区域列表 -->
  <div class="area-list">
    <div class="area-item" 
         *ngFor="let area of areas"
         [class.active]="selectedArea?.id === area.id"
         (click)="selectArea(area)">
      
      <div class="area-header">
        <div class="area-icon" [style.background]="area.color">
          {{ area.icon }}
        </div>
        <div class="area-info">
          <h6>{{ area.name }}</h6>
          <span class="area-style">{{ area.styleDescription }}</span>
        </div>
        <span class="area-status" [class]="area.status">
          {{ getStatusText(area.status) }}
        </span>
      </div>
      
      <div class="area-details">
        <div class="detail-item">
          <span class="label">责任人:</span>
          <span class="value">{{ area.assignedTo || '未分配' }}</span>
        </div>
        <div class="detail-item">
          <span class="label">五维验证:</span>
          <span class="value">{{ getCompletedDimensions(area) }}/5</span>
        </div>
      </div>
      
      <div class="area-actions">
        <button class="btn-ghost btn-xs" (click)="editArea(area); $event.stopPropagation()">
          编辑
        </button>
        <button class="btn-ghost btn-xs" (click)="deleteArea(area.id); $event.stopPropagation()">
          删除
        </button>
      </div>
    </div>
  </div>
</div>

2. 区域数据模型

export interface Area {
  id: string;
  name: string;
  icon: string;              // emoji或图标
  color: string;             // 区域标识颜色
  styleDescription: string;  // 风格描述
  status: 'pending' | 'in-progress' | 'completed';
  
  // 分工
  assignedTo?: string;       // 责任人ID
  assignedRole?: string;     // 角色
  
  // 五维验证数据
  dimensionVerifications: {
    color?: DimensionVerification;
    form?: DimensionVerification;
    texture?: DimensionVerification;
    pattern?: DimensionVerification;
    lighting?: DimensionVerification;
  };
  
  // 特殊需求
  specialRequirements?: string[];
  
  // 参考素材(区域专属)
  dedicatedMaterials?: string[]; // 素材ID列表
  
  createdAt: Date;
  updatedAt: Date;
}

3. 区域添加/编辑对话框

<div class="area-dialog-overlay" *ngIf="showAreaDialog">
  <div class="area-dialog">
    <div class="dialog-header">
      <h5>{{ editingArea ? '编辑区域' : '新增区域' }}</h5>
      <button class="btn-close" (click)="closeAreaDialog()">×</button>
    </div>
    
    <div class="dialog-body">
      <form [formGroup]="areaForm">
        <!-- 区域名称 -->
        <div class="form-group">
          <label>区域名称</label>
          <input type="text" 
                 formControlName="name"
                 placeholder="如:客厅、婴儿房、主卧等">
        </div>
        
        <!-- 预设选择 -->
        <div class="form-group">
          <label>选择预设</label>
          <div class="preset-grid">
            <button type="button" 
                    class="preset-btn"
                    *ngFor="let preset of areaPresets"
                    [class.selected]="selectedPreset?.id === preset.id"
                    (click)="applyPreset(preset)">
              <span class="preset-icon">{{ preset.icon }}</span>
              <span class="preset-name">{{ preset.name }}</span>
            </button>
          </div>
        </div>
        
        <!-- 风格描述 -->
        <div class="form-group">
          <label>风格描述</label>
          <textarea formControlName="styleDescription"
                    rows="3"
                    placeholder="如:黑白灰很酷的现代风格 或 色彩更儿童化的温馨空间"></textarea>
        </div>
        
        <!-- 标识颜色 -->
        <div class="form-group">
          <label>标识颜色</label>
          <input type="color" formControlName="color">
        </div>
        
        <!-- 责任人分配 -->
        <div class="form-group">
          <label>责任人</label>
          <select formControlName="assignedTo">
            <option value="">-- 未分配 --</option>
            <option *ngFor="let user of availableUsers" [value]="user.id">
              {{ user.name }} ({{ user.role }})
            </option>
          </select>
        </div>
        
        <!-- 特殊需求 -->
        <div class="form-group">
          <label>特殊需求</label>
          <div class="requirement-tags">
            <input type="text" 
                   #requirementInput
                   placeholder="按Enter添加需求标签"
                   (keyup.enter)="addRequirement(requirementInput.value); requirementInput.value = ''">
            <div class="tags-list">
              <span class="tag" *ngFor="let req of specialRequirements; let i = index">
                {{ req }}
                <button class="remove" (click)="removeRequirement(i)">×</button>
              </span>
            </div>
          </div>
        </div>
      </form>
    </div>
    
    <div class="dialog-footer">
      <button class="btn-secondary" (click)="closeAreaDialog()">取消</button>
      <button class="btn-primary" (click)="saveArea()">保存</button>
    </div>
  </div>
</div>

4. 区域预设配置

const areaPresets: AreaPreset[] = [
  {
    id: 'living-room',
    name: '客厅',
    icon: '🛋️',
    color: '#4A90E2',
    styleDescription: '现代简约,明亮开阔',
    defaultRequirements: ['开放式布局', '充足采光', '舒适氛围']
  },
  {
    id: 'baby-room',
    name: '婴儿房',
    icon: '👶',
    color: '#FFB6C1',
    styleDescription: '色彩丰富,童趣温馨',
    defaultRequirements: ['安全环保', '柔和色彩', '储物充足', '易于清洁']
  },
  {
    id: 'master-bedroom',
    name: '主卧',
    icon: '🛏️',
    color: '#9B59B6',
    styleDescription: '宁静优雅,私密舒适',
    defaultRequirements: ['隔音效果', '柔和灯光', '收纳空间']
  },
  {
    id: 'kitchen',
    name: '厨房',
    icon: '🍳',
    color: '#E67E22',
    styleDescription: '实用高效,易于清洁',
    defaultRequirements: ['动线合理', '台面充足', '通风良好', '防油防水']
  },
  {
    id: 'bathroom',
    name: '卫生间',
    icon: '🚿',
    color: '#3498DB',
    styleDescription: '清新明亮,干湿分离',
    defaultRequirements: ['防水防滑', '通风除湿', '储物空间']
  },
  {
    id: 'study',
    name: '书房',
    icon: '📚',
    color: '#27AE60',
    styleDescription: '安静专注,书香氛围',
    defaultRequirements: ['采光充足', '隔音效果', '书柜充足']
  },
  {
    id: 'dining',
    name: '餐厅',
    icon: '🍽️',
    color: '#F39C12',
    styleDescription: '温馨舒适,聚餐氛围',
    defaultRequirements: ['空间适中', '照明充足', '易于清洁']
  },
  {
    id: 'custom',
    name: '自定义',
    icon: '✏️',
    color: '#95A5A6',
    styleDescription: '',
    defaultRequirements: []
  }
];

5. 区域切换与对比视图

<div class="area-comparison-view">
  <div class="comparison-header">
    <h5>区域参数对比</h5>
    <button class="btn-ghost" (click)="exportComparison()">导出对比表</button>
  </div>
  
  <table class="comparison-table">
    <thead>
      <tr>
        <th>维度/区域</th>
        <th *ngFor="let area of areas">{{ area.name }}</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>色彩</td>
        <td *ngFor="let area of areas">
          <span class="status-badge" [class]="area.dimensionVerifications.color?.status">
            {{ getStatusText(area.dimensionVerifications.color?.status) }}
          </span>
        </td>
      </tr>
      <tr>
        <td>形体</td>
        <td *ngFor="let area of areas">
          <span class="status-badge" [class]="area.dimensionVerifications.form?.status">
            {{ getStatusText(area.dimensionVerifications.form?.status) }}
          </span>
        </td>
      </tr>
      <tr>
        <td>质感</td>
        <td *ngFor="let area of areas">
          <span class="status-badge" [class]="area.dimensionVerifications.texture?.status">
            {{ getStatusText(area.dimensionVerifications.texture?.status) }}
          </span>
        </td>
      </tr>
      <tr>
        <td>纹理</td>
        <td *ngFor="let area of areas">
          <span class="status-badge" [class]="area.dimensionVerifications.pattern?.status">
            {{ getStatusText(area.dimensionVerifications.pattern?.status) }}
          </span>
        </td>
      </tr>
      <tr>
        <td>灯光</td>
        <td *ngFor="let area of areas">
          <span class="status-badge" [class]="area.dimensionVerifications.lighting?.status">
            {{ getStatusText(area.dimensionVerifications.lighting?.status) }}
          </span>
        </td>
      </tr>
    </tbody>
  </table>
</div>

C5. 分工和人员系统

功能设计

1. 人员角色定义

export interface CollaborationUser {
  id: string;
  name: string;
  role: 'designer' | 'customer-service' | 'team-leader' | 'client';
  avatar?: string;
  permissions: {
    canEditColor: boolean;
    canEditForm: boolean;
    canEditTexture: boolean;
    canEditPattern: boolean;
    canEditLighting: boolean;
    canApprove: boolean;
  };
}

2. 分工面板

<div class="collaboration-assignment-panel">
  <h6>分工管理</h6>
  
  <!-- 按维度分工 -->
  <div class="dimension-assignments">
    <div class="assignment-row" *ngFor="let dimension of dimensions">
      <span class="dimension-name">{{ dimension.name }}</span>
      <select [(ngModel)]="dimensionAssignments[dimension.key]"
              (change)="updateAssignment(dimension.key, $event.target.value)">
        <option value="">-- 未分配 --</option>
        <option *ngFor="let user of eligibleUsers[dimension.key]" 
                [value]="user.id">
          {{ user.name }} ({{ user.role }})
        </option>
      </select>
      <span class="assignment-status">
        {{ getAssignmentStatus(dimension.key) }}
      </span>
    </div>
  </div>
  
  <!-- 按区域分工 -->
  <div class="area-assignments" *ngIf="areas.length > 0">
    <h6>区域责任人</h6>
    <div class="assignment-row" *ngFor="let area of areas">
      <span class="area-name">{{ area.name }}</span>
      <select [(ngModel)]="area.assignedTo"
              (change)="updateAreaAssignment(area.id, $event.target.value)">
        <option value="">-- 未分配 --</option>
        <option *ngFor="let user of availableUsers" 
                [value]="user.id">
          {{ user.name }} ({{ user.role }})
        </option>
      </select>
    </div>
  </div>
  
  <!-- 协作状态跟踪 -->
  <div class="collaboration-tracking">
    <h6>协作状态</h6>
    <div class="tracking-grid">
      <div class="tracking-item" *ngFor="let user of activeUsers">
        <div class="user-avatar">
          <img [src]="user.avatar || defaultAvatar" [alt]="user.name">
          <span class="online-indicator" *ngIf="user.isOnline"></span>
        </div>
        <div class="user-info">
          <span class="name">{{ user.name }}</span>
          <span class="role">{{ getRoleName(user.role) }}</span>
        </div>
        <div class="user-tasks">
          <span class="task-count">{{ getUserTaskCount(user.id) }} 项任务</span>
          <span class="completion">{{ getUserCompletion(user.id) }}% 完成</span>
        </div>
      </div>
    </div>
  </div>
</div>

3. 审批流程

<div class="approval-workflow">
  <h6>审批流程</h6>
  
  <div class="workflow-steps">
    <div class="step" 
         *ngFor="let step of approvalSteps; let i = index"
         [class.completed]="step.status === 'completed'"
         [class.active]="step.status === 'in-progress'">
      
      <div class="step-number">{{ i + 1 }}</div>
      <div class="step-content">
        <h6>{{ step.title }}</h6>
        <p>{{ step.description }}</p>
        
        <div class="step-assignee">
          <span class="label">审批人:</span>
          <span class="value">{{ step.assignee?.name || '待分配' }}</span>
        </div>
        
        <div class="step-actions" *ngIf="step.status === 'in-progress' && canApprove(step)">
          <button class="btn-success btn-sm" (click)="approveStep(step.id)">
            通过
          </button>
          <button class="btn-danger btn-sm" (click)="rejectStep(step.id)">
            驳回
          </button>
        </div>
        
        <div class="step-result" *ngIf="step.status === 'completed'">
          <span class="result-badge" [class]="step.result">
            {{ step.result === 'approved' ? '已通过' : '已驳回' }}
          </span>
          <span class="result-time">{{ step.completedAt | date:'MM-dd HH:mm' }}</span>
        </div>
      </div>
    </div>
  </div>
</div>

4. 审批逻辑

interface ApprovalStep {
  id: string;
  title: string;
  description: string;
  assignee?: CollaborationUser;
  status: 'pending' | 'in-progress' | 'completed';
  result?: 'approved' | 'rejected';
  completedAt?: Date;
  comments?: string;
}

const approvalSteps: ApprovalStep[] = [
  {
    id: 'dimension-verification',
    title: '五维验证审核',
    description: '设计师完成五个维度的验证',
    status: 'pending'
  },
  {
    id: 'customer-service-review',
    title: '客服审核',
    description: '客服确认需求理解正确',
    status: 'pending'
  },
  {
    id: 'team-leader-approval',
    title: '组长审批',
    description: '组长审批整体方案',
    status: 'pending'
  },
  {
    id: 'client-confirmation',
    title: '客户确认',
    description: '客户最终确认',
    status: 'pending'
  }
];

approveStep(stepId: string): void {
  const step = this.approvalSteps.find(s => s.id === stepId);
  if (step) {
    step.status = 'completed';
    step.result = 'approved';
    step.completedAt = new Date();
    
    // 自动启动下一步
    const nextStepIndex = this.approvalSteps.indexOf(step) + 1;
    if (nextStepIndex < this.approvalSteps.length) {
      this.approvalSteps[nextStepIndex].status = 'in-progress';
    }
    
    // 检查是否所有步骤都完成
    const allApproved = this.approvalSteps.every(s => s.result === 'approved');
    if (allApproved) {
      this.onAllStepsApproved();
    }
  }
}

rejectStep(stepId: string): void {
  const step = this.approvalSteps.find(s => s.id === stepId);
  if (step) {
    const reason = prompt('请输入驳回原因:');
    if (reason) {
      step.status = 'completed';
      step.result = 'rejected';
      step.comments = reason;
      step.completedAt = new Date();
      
      // 通知相关人员
      this.notifyRejection(step);
    }
  }
}

4. 技术实施建议

需要新增的组件

src/app/shared/components/
├── color-wheel-visualizer/          # 色轮可视化组件
│   ├── color-wheel-visualizer.component.ts
│   ├── color-wheel-visualizer.component.html
│   └── color-wheel-visualizer.component.scss
│
├── dimension-verification/          # 维度验证组件
│   ├── dimension-verification.component.ts
│   ├── dimension-verification.component.html
│   └── dimension-verification.component.scss
│
├── annotation-tool/                 # 标注工具组件
│   ├── annotation-tool.component.ts
│   ├── annotation-tool.component.html
│   └── annotation-tool.component.scss
│
├── area-management/                 # 区域管理组件
│   ├── area-management.component.ts
│   ├── area-management.component.html
│   └── area-management.component.scss
│
├── furniture-form-selector/         # 软装形体选择器
│   ├── furniture-form-selector.component.ts
│   ├── furniture-form-selector.component.html
│   └── furniture-form-selector.component.scss
│
├── texture-comparison/              # 质感对比组件
│   ├── texture-comparison.component.ts
│   ├── texture-comparison.component.html
│   └── texture-comparison.component.scss
│
├── pattern-visualizer/              # 纹理可视化组件
│   ├── pattern-visualizer.component.ts
│   ├── pattern-visualizer.component.html
│   └── pattern-visualizer.component.scss
│
└── lighting-distribution-chart/     # 光占比图表组件
    ├── lighting-distribution-chart.component.ts
    ├── lighting-distribution-chart.component.html
    └── lighting-distribution-chart.component.scss

需要修改的现有文件

1. requirements-confirm-card.ts

  • 移除需求映射标签页相关代码
  • 添加五维验证数据结构
  • 添加区域管理逻辑
  • 集成标注工具
  • 实现分工和审批流程

2. requirements-confirm-card.html

  • 重构协作验证标签页
  • 增强素材分析展示
  • 添加区域管理UI
  • 集成新组件

3. requirements-confirm-card.scss

  • 新增五维验证样式
  • 标注工具样式
  • 区域管理样式
  • 响应式布局优化

数据模型调整

新建接口文件:

src/app/models/
├── collaboration-verification.interface.ts  # 协作验证相关接口
├── annotation.interface.ts                  # 标注相关接口
├── area-management.interface.ts             # 区域管理相关接口
└── approval-workflow.interface.ts           # 审批流程相关接口

API接口需求

// 需要后端提供的API接口

// 1. 灯光分析增强
POST /api/analysis/lighting/ratio            // 计算光比
POST /api/analysis/lighting/distribution     // 计算光占比

// 2. 标注管理
POST /api/annotations                         // 创建标注
GET /api/annotations/:projectId              // 获取项目标注
PUT /api/annotations/:id                     // 更新标注
DELETE /api/annotations/:id                  // 删除标注

// 3. 区域管理
POST /api/areas                              // 创建区域
GET /api/areas/:projectId                    // 获取项目区域
PUT /api/areas/:id                           // 更新区域
DELETE /api/areas/:id                        // 删除区域

// 4. 分工管理
POST /api/assignments                        // 分配任务
GET /api/assignments/:projectId              // 获取项目分工
PUT /api/assignments/:id                     // 更新分工

// 5. 审批流程
POST /api/approvals/:stepId/approve          // 审批通过
POST /api/approvals/:stepId/reject           // 审批驳回
GET /api/approvals/:projectId/status         // 获取审批状态

5. 实施分阶段建议

阶段1:素材分析增强(预计5-7天)

优先级:高

任务清单:

  • 创建色轮可视化组件
  • 实现软装形体选择器
  • 优化质感对比展示
  • 增强纹理图案可视化
  • 补充灯光分析(光比、光占比)
  • 实现全展示模式切换
  • 添加分析报告导出功能

验收标准:

  • 色轮能正确显示色彩分布
  • 软装形体可选择并保存
  • 质感亮光/哑光对比清晰
  • 灯光分析包含光比和光占比数据
  • 全展示模式能展开所有分析细节

阶段2:需求映射隐藏(预计1-2天)

优先级:中

任务清单:

  • 移除需求映射标签页UI
  • 实现后台自动触发机制
  • 保留映射数据接口
  • 测试自动映射功能
  • 添加开发模式可见性(可选)

验收标准:

  • 需求映射标签页不可见
  • 素材分析完成后自动生成映射
  • 映射数据正确传递给父组件
  • 不影响方案确认阶段的显示

阶段3:协作验证重构(预计10-14天)

优先级:高(核心)

子阶段3.1:五维验证模块(3-4天)

  • 创建维度验证数据模型
  • 实现五维验证UI布局
  • 创建dimension-verification组件
  • 实现维度切换逻辑
  • 添加验证状态管理

子阶段3.2:素材关联系统(2-3天)

  • 实现拖拽关联功能(使用CDK Drag&Drop)
  • 实现下拉选择关联
  • 添加相关度计算
  • 实现素材高亮显示

子阶段3.3:标注工具集成(3-4天)

  • 创建annotation-tool组件
  • 实现SVG标注层
  • 支持文字、箭头、高亮、圆圈、矩形标注
  • 实现标注保存和加载
  • 添加标注列表管理

子阶段3.4:区域细分管理(2-3天)

  • 创建area-management组件
  • 实现区域添加/编辑对话框
  • 配置区域预设
  • 实现区域切换逻辑
  • 添加区域对比视图

子阶段3.5:分工和人员系统(2-3天)

  • 定义用户角色和权限
  • 实现分工管理面板
  • 实现协作状态跟踪
  • 实现审批流程
  • 添加通知机制

验收标准:

  • 五个维度可独立验证
  • 素材能正确关联到各维度
  • 标注工具功能完整且流畅
  • 区域可添加、编辑、删除
  • 分工和审批流程正常运行

6. 验收标准

功能完整性验收

素材分析模块:

  • ✅ 所有五个维度(色彩、形体、质感、纹理、灯光)都有完整的分析数据
  • ✅ 色轮可视化正确展示色彩分布
  • ✅ 灯光分析包含光比和光占比
  • ✅ 可切换精简视图和完整展示模式
  • ✅ 可导出分析报告(PDF/Excel/JSON)

协作验证模块:

  • ✅ 五维验证模块独立可操作
  • ✅ 素材能通过拖拽或选择关联到维度
  • ✅ 标注工具支持5种标注类型
  • ✅ 区域可自由添加和管理
  • ✅ 分工分配正常,审批流程完整

系统集成:

  • ✅ 需求映射在后台自动生成
  • ✅ 数据正确传递给父组件
  • ✅ 不影响其他模块功能

用户体验标准

交互体验:

  • 响应时间 < 200ms(标注工具除外)
  • 拖拽操作流畅无卡顿
  • 标注绘制实时反馈
  • 表单验证及时提示

视觉设计:

  • UI风格与整体系统一致
  • 色彩搭配和谐
  • 图标清晰易识别
  • 布局合理不拥挤

易用性:

  • 操作步骤明确,不超过3步
  • 提供操作提示和帮助文档
  • 支持键盘快捷键(标注工具)
  • 错误提示友好明确

性能要求:

  • 素材列表加载 < 1s
  • 色轮渲染 < 500ms
  • 标注保存 < 300ms
  • 区域切换 < 200ms

数据准确性

  • ✅ 分析数据与实际图片内容相符
  • ✅ 光比计算误差 < 10%
  • ✅ 色彩提取准确率 > 90%
  • ✅ 关联关系正确保存和加载

兼容性

  • ✅ 支持Chrome、Edge、Firefox最新版本
  • ✅ 响应式设计适配1366px及以上分辨率
  • ✅ 支持触摸屏操作(标注工具)

7. 风险评估与建议

潜在风险

技术风险:

  1. 色轮可视化性能 - 大量颜色数据可能影响渲染性能

    • 建议:使用Canvas替代SVG,实现虚拟滚动
  2. 标注工具复杂度 - SVG操作和状态管理复杂

    • 建议:使用成熟的库如Fabric.js或Konva.js
  3. 拖拽关联稳定性 - CDK Drag&Drop可能有兼容性问题

    • 建议:充分测试,准备降级方案

业务风险:

  1. 区域细分粒度 - 过细可能导致操作复杂

    • 建议:限制最大区域数量(如10个)
  2. 审批流程僵化 - 固定流程可能不适合所有项目

    • 建议:支持自定义审批流程

优化建议

性能优化:

  • 使用虚拟滚动加载大量素材
  • 图片懒加载和预加载策略
  • 标注数据分页加载
  • 实施增量更新策略

用户体验优化:

  • 添加操作引导(首次使用)
  • 提供快捷键支持
  • 实现撤销/重做功能
  • 添加实时保存提示

扩展性建议:

  • 标注工具支持插件扩展
  • 区域类型可配置
  • 审批流程可自定义
  • 支持第三方集成(如AI分析)

8. 总结

本优化方案围绕三个核心目标:

  1. 素材分析完全展示 - 通过增强色彩、形体、质感、纹理、灯光五个维度的可视化和数据完整性,确保所有采集的参考信息都能充分展示。

  2. 需求映射后台化 - 将用户不需要直接操作的需求映射功能隐藏,改为自动触发,简化用户流程。

  3. 协作验证深度重构 - 这是最核心的改进,通过五维验证、素材关联、标注工具、区域细分、分工管理等功能,实现真正的协作式需求验证。

实施建议采用分阶段推进,优先完成素材分析增强和协作验证重构,这两个是高优先级且用户价值最大的功能。


附录

A. 相关技术栈

  • Angular: v16+
  • Angular CDK: Drag&Drop模块
  • D3.js: 色轮可视化
  • ECharts: 图表绘制
  • Fabric.js/Konva.js: 标注工具(可选)
  • RxJS: 响应式数据流

B. 参考资源

C. 联系与支持

如有疑问或需要进一步讨论,请联系:

  • 项目负责人:[待填写]
  • 技术负责人:[待填写]
  • 设计负责人:[待填写]

文档版本: v1.0
创建日期: {{ currentDate }}
最后更新: {{ currentDate }}
状态: 待审核